188

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.

N.N.
  • 8,336
  • 12
  • 54
  • 94
prismofeverything
  • 8,799
  • 8
  • 38
  • 53

6 Answers6

230

I think this will do it for you:

location / {
    try_files /base.html =404;
}
kolbyjack
  • 17,660
  • 5
  • 48
  • 35
Alex Howansky
  • 50,515
  • 8
  • 78
  • 98
  • 5
    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. – Alex Howansky Aug 11 '11 at 14:47
  • 25
    Using ``try_files '' /base.html;`` (empty string as the first argument to ``try_files``) avoids the lookup of a file called ``$uri``. – davidjb Mar 27 '15 at 01:31
  • 21
    `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. – William Turrell Sep 25 '15 at 12:35
40

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;
}
Kevan Stannard
  • 977
  • 7
  • 12
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.

kolbyjack
  • 17,660
  • 5
  • 48
  • 35
21

This worked for me:

location / {
    try_files $uri $uri/ /base.html;
}
Abhishek
  • 968
  • 10
  • 16
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/;
}
Mark Chackerian
  • 21,866
  • 6
  • 108
  • 99
8

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.

Etherealone
  • 3,488
  • 2
  • 37
  • 56