I am trying to get nginx
to work with my pushState
-based URI handling that backbone.js
manages for me in an Javascript app.
Right now accessing URI's with one level, eg. example.com/users
works well, but not two-level or deeper URI's, such as example.com/users/all
, which is mentioned in the Backbone documentation:
For example, if you have a route of /documents/100, your web server must be able to serve that page, if the browser visits that URL directly
So, being far from acquainted with nginx's rewrite options, I am still sure that I can do something like rewrite ^ /index.html;
to redirect everything to my index.html
, but loosing out on any eventual static files (images, javascript & css) stored on the same server which I need to be able to access.
So what should I do instead with the below shown, current configuration, to make this work?
server {
listen 80;
server_name example.com;
location / {
root /var/www/example.com;
try_files $uri /index.html;
}
}
I ended up going with this solution:
This way, at least I still get proper 404 errors if a file isn't found.
With client side app paths:
Use:
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 toexample.com/foo/bar/baz/js/app.js
instead ofexample.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
.Here is what i did to my application. Every route ending with a '/' (except the root it self) will serve
index.html
:You can also prefix your route :
and then :
Or define a rule for each case.
Since there may be ajax request api, the following suits for this case,
I managed it like this: