nginx: send all requests to a single html page
Asked Answered
M

6

194

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.

Merrygoround answered 11/8, 2011 at 14:27 Comment(2)
Thanks for asking this question so the answer was ready for me :-)Microbe
You were almost there! 'rewrite ^ /base.html break;' should work, as pointed by @kolbyjackDiphyodont
M
236

I think this will do it for you:

location / {
    try_files /base.html =404;
}
Maelstrom answered 11/8, 2011 at 14:30 Comment(3)
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.Maelstrom
Using try_files '' /base.html; (empty string as the first argument to try_files) avoids the lookup of a file called $uri.Hypodermic
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.Ringhals
K
43

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;
}
Karankaras answered 15/2, 2015 at 23:31 Comment(2)
try_files '' /base.html =404; (see above)Precursor
This worked for me, but I actually did not need the location = /base.html { expires 30s } part.Icy
S
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.

Sarver answered 11/8, 2011 at 22:51 Comment(0)
A
23

This worked for me:

location / {
    try_files $uri $uri/ /base.html;
}
Afro answered 3/6, 2018 at 20:31 Comment(3)
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.Idolum
@ParamSiddharth What about getting 404 on refreshPancratium
How do you handle refreshing problem that gives 404 @AfroPancratium
H
20

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/;
}
Hindenburg answered 2/8, 2017 at 14:39 Comment(1)
tks, this works for me, but the tailing slash at alias is importantCeroplastics
S
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.

Spile answered 8/3, 2015 at 23:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.