2

I have read a dozen rewite questions. Most questions are for .php but I have simple .html files so about => about.html .But I am not able to get nginx to do this:

  • accept url with or without "/"
  • redirect domain.com/about and domain.com/about/ to domain.com/about.html
  • add trailing slash to the URL so if I write domain.com/about it writes domain.com/about/

I have tried with this code rewrite ^/([a-zA-Z0-9]+)$ /$1.html; but it gives me 404 error on url ending with "/". Also tried this rewrite ^([a-zA-Z0-9]+)/?$ $1.html with same error.

Some suggest I should be using try try_files?

I tried this also which gives a 500 error:

location / { 
rewrite ^(.*)$ /%1 redirect; 
rewrite ^/([^\.]+)$ /$1.html break; 
}

I tried to convert apache to nginx (winginx.com) from suggestion here with no success.

This code does not work. I am trying to redirect and add trailing slash:

if (!-e $request_filename){
rewrite ^/(.*)/$ /$1 redirect;
}
if (!-e $request_filename){
rewrite ^/(.*[^/])$ /$1/ redirect;
}

Any suggestion would make me happy.

Community
  • 1
  • 1
Asle
  • 767
  • 2
  • 8
  • 22
  • The simplest solution would be to rename `about.html` to `about/index.html` then `nginx` pretty much does what you want with its index module. – Richard Smith Jan 12 '17 at 17:53
  • 1
    This sounds a bit overkill. Instead of single html files I would have to make a folder for every html file and put the contents in a index.html file into that folder?!? – Asle Jan 12 '17 at 19:43

2 Answers2

2

I have tested this configuration and it appears to meet your requirements (YMMV):

root /path/to/root;

location / {
    try_files $uri @rewrite;
}
location @rewrite {
    rewrite ^(.*[^/])$ $1/ permanent;
    rewrite ^(.*)/$ $1.html break;
}

The first location attempts to serve the file as is which is necessary for resource files. Otherwise it defers to the named location.

The named location will permanently redirect any URIs which do not end in /. Otherwise, the .html file is served.

See this document and this document for details.

Richard Smith
  • 45,711
  • 6
  • 82
  • 81
  • Hi, sorry this is not working. With this config I get a 404 page on index.html (root). When I click on e.g. "projects" it shows projects.html and the URL is "http://example.com/projects/" but all css and images are broken. On the page projects I click on link ***"about"*** (the page is about.html) and I get "http://example.com/projects/about/" -> It should be "http://example.com/about/" and from there it goes to "http://example.com/projects/about/about/about/ ...." etc. so there is an internal loop. – Asle Jan 13 '17 at 16:17
  • Using path relative resources (css & js) will not work with your scheme, as the browser assumes that the trailing `/` is a subdirectory. The link to `about.html` should probably be `/about.html` to avoid getting `/project/about.html` for the same reason. I don't get the internal loop - but it is a big risk with these types of scheme. – Richard Smith Jan 13 '17 at 16:30
  • I agree with the risk Richard! I rewrote the paths to absolute and the css and images are working. Also made the links absolute. That fixed the wrong URLs . Thanks for the insight and for understanding what I was trying to solve! – Asle Jan 16 '17 at 22:04
0

I think a try_files would be appropriate here. For example:

location /about {
    try_files about.html;
}
Faisal Memon
  • 1,047
  • 7
  • 7
  • Will work for about.html but I have many files, about.html, contact.html, projects.html, gallery.html etc... – Asle Jan 12 '17 at 19:44
  • You can create a block for each one or use a regex like: `location ~ ^/(.*)/?$ {try_files $1.html;}` – Faisal Memon Jan 13 '17 at 21:22