197

Using nginx, I want to preserve the url, but actually load the same page no matter what. I will use the url with History.getState() to route the requests in my javascript app. It seems like it should be a simple thing to do?

location / {
    rewrite (.*) base.html break;
}

works, but redirects the url? I still need the url, I just want to always use the same page.

2
  • 9
    Thanks for asking this question so the answer was ready for me :-) Commented May 7, 2016 at 20:38
  • You were almost there! 'rewrite ^ /base.html break;' should work, as pointed by @kolbyjack Commented Feb 13, 2021 at 14:59

6 Answers 6

241

I think this will do it for you:

location / {
    try_files /base.html =404;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Note -- this will first check for the file requested, and if it's not there, it will serve base.html. So make sure that you've got no old extra files sitting around in your document root directory, or they'll get served directly if queried.
Using try_files '' /base.html; (empty string as the first argument to try_files) avoids the lookup of a file called $uri.
try_files '' /base.html; gave me a redirection problem and an internal server error, but modifying it to try_files '' /base.html =404; fixed that, if it helps anyone.
If you have other files that you want to be served (e.g. assets), you need to include $uri in the command, otherwise nginx will always serve base.html, even if the other file exists (at least I checked this for files in subdirs). Thus, use try_files $uri /base.html =404; instead if you want to serve existing files.
45

Using just try_files didn't work for me - it caused a rewrite or internal redirection cycle error in my logs.

The Nginx docs had some additional details:

http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files

So I ended up using the following:

root /var/www/mysite;

location / {
    try_files $uri /base.html;
}

location = /base.html {
    expires 30s;
}

2 Comments

try_files '' /base.html =404; (see above)
This worked for me, but I actually did not need the location = /base.html { expires 30s } part.
26

Your original rewrite should almost work. I'm not sure why it would be redirecting, but I think what you really want is just

rewrite ^ /base.html break;

You should be able to put that in a location or directly in the server.

Comments

24

This worked for me:

location / {
    try_files $uri $uri/ /base.html;
}

3 Comments

For a React application's production build, this works: try_files $uri $uri/ /index.html =404;. Why? Because the build comprises more other files, including static JavaScript and CSS files.
@ParamSiddharth What about getting 404 on refresh
How do you handle refreshing problem that gives 404 @Abhishek
21

This worked for me:

location / {
    alias /path/to/my/indexfile/;
    try_files $uri /index.html;
}

This allowed me to create a catch-all URL for a javascript single-page app. All static files like css, fonts, and javascript built by npm run build will be found if they are in the same directory as index.html.

If the static files were in another directory, for some reason, you'd also need something like:

# Static pages generated by "npm run build"
location ~ ^/css/|^/fonts/|^/semantic/|^/static/ {
    alias /path/to/my/staticfiles/;
}

1 Comment

tks, this works for me, but the tailing slash at alias is important
9

The correct way would be:

location / {
    rewrite (.*) base.html last;
}

Using last will make nginx find a new suitable location block according to the result of rewriting.

try_files is also a perfectly valid approach to this problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.