I am trying to get nginx
to work with my pushState
-based URI handling that backbone.js
manages for me in an Javascript app.
R
With client side app paths:
/
/foo
/foo/bar
/foo/bar/baz
/foo/bar/baz/123
/tacos
/tacos/123
Use:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
gzip_static on;
location / {
try_files $uri $uri/ /index.html;
}
# Attempt to load static files, if not found route to @rootfiles
location ~ (.+)\.(html|json|txt|js|css|jpg|jpeg|gif|png|svg|ico|eot|otf|woff|woff2|ttf)$ {
try_files $uri @rootfiles;
}
# Check for app route "directories" in the request uri and strip "directories"
# from request, loading paths relative to root.
location @rootfiles {
rewrite ^/(?:foo/bar/baz|foo/bar|foo|tacos)/(.*) /$1 redirect;
}
}
While @Adam-Waite's answer works for the root and paths at the root level, using if within the location context is considered an antipattern, often seen when converting Apache style directives. See: http://wiki.nginx.org/IfIsEvil.
The other answers do not cover routes with directory depth for my use case in a similar React app using react-router and HTML5 pushState enabled. When a route is loaded or refreshed within a "directory" such as example.com/foo/bar/baz/213123
my index.html file will reference the js file at a relative path and resolve to example.com/foo/bar/baz/js/app.js
instead of example.com/js/app.js
.
For cases with directory depth beyond the first level such as /foo/bar/baz
, note the order of the directories declared in the @rootfiles directive: the longest possible paths need to go first, followed by the next shallower path /foo/bar
and finally /foo
.