2

I'm trying to setup a Nginx configuration for nice URLs without .html extension.

What I currently have works, but the / URI redirects to /index and I don't want that.

The URL rewrite rules should be as follows:

/index.html -> /
/test.html -> /test
/subpage/ -> /subpage
/subpage/test.html -> /subpage/test
/sub/sub/index.html -> /sub/sub
/sub/sub/ -> /sub/sub
/somepage/ -> /somepage
/somepage.html -> /somepage

Here is the configuration:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    set $root /app/www/public;
    if (!-d /app/www/public) {
        set $root /config/www;
    }
    root $root;
    index index.html;
    
    error_page 401 /401;
    error_page 403 /403;
    error_page 404 /404;
    error_page 500 502 503 504 /500;
    
    location / {
        #redirect index.html to /
        if ( $request_uri ~ "index.html" ) {
            rewrite ^(.*)/ $1/ permanent;
        }

        #remove .html from request
        rewrite ^/(.*)\.html$ /$1 permanent;
        
        #remove the trailing /
        rewrite ^/(.*)/$ /$1 permanent;

        try_files $uri.html $uri/ $uri =404;
    }
    
    location ~* \.(jpg|jpeg|png|gif|ico)$ {
       expires 30d;
    }
    location ~* \.(css|js)$ {
       expires 7d;
    }

    # deny access to .htaccess/.htpasswd files
    location ~ /\.ht {
        deny all;
    }
}

NOTE: this Nginx is running in a docker container.

3
  • Not sure if there is a directory /somepage/ and at the same time there is a somepage.html . Any advice on that?
    – Rumplin
    Commented Sep 20, 2022 at 18:34
  • I'll bet it is a problem with if ( $request_uri ~ "index.html" ) because an if statement inside a location has non-obvious behavior: nginx.com/resources/wiki/start/topics/depth/ifisevil Commented Sep 20, 2022 at 19:01
  • Good point on the if statement. I'm pretty new to Nginx, coming from IIS there are a lot of things that are upside down from my point of view.
    – Rumplin
    Commented Sep 20, 2022 at 21:29

1 Answer 1

1

I got it to work with this configuration which I tested on nginx/1.18.0 (Ubuntu):

    index XXXXXX.DISABLE.INDEX.DOCUMENT.XXXXXX;
    location / {
        #remove index.html from request
        rewrite ^/(.*)/index(\.html)?$ /$1 permanent;    
        rewrite ^/(.*)index(\.html)?$ /$1 permanent;        

        #remove .html from request
        rewrite ^/(.*)\.html$ /$1 permanent;
        
        #remove the trailing /
        rewrite ^/(.*)/$ /$1 permanent;
        
        try_files $uri ${uri}/index.html ${uri}.html =404;
    }

By disabling the index functionality, you can handle add index.html to the try_files which is more compatible with the rewrite rules.

You can control if /sub/index.html or /sub.html takes precedence for a request for /sub by changing the order of ${uri}/index.html and ${uri}.html in try_files.

Tests:

  • curl --head http://localhost/ -> 200 OK (powered by /index.html)
  • curl --head http://localhost/index -> 301 Moved Permanently to Location: http://localhost/
  • curl --head http://localhost/index.html -> 301 Moved Permanently to Location: http://localhost/
  • curl --head http://localhost/page -> 200 OK (powered by /page.html)
  • curl --head http://localhost/page.html -> 301 Moved Permanently to Location: http://localhost/page
  • curl --head http://localhost/sub -> 200 OK (powered by /sub/index.html)
  • curl --head http://localhost/sub/ -> 301 Moved Permanently to Location: http://localhost/sub
  • curl --head http://localhost/sub/ -> 301 Moved Permanently to Location: http://localhost/sub
  • curl --head http://localhost/sub/index -> 301 Moved Permanently to Location: http://localhost/sub
  • curl --head http://localhost/sub/index.html -> 301 Moved Permanently to Location: http://localhost/sub
3
  • Thank you very much, this is exactly what I was looking for.
    – Rumplin
    Commented Sep 20, 2022 at 20:56
  • is there a difference between ${uri} and $uri ?
    – Rumplin
    Commented Sep 20, 2022 at 21:04
  • 1
    No. Using the curly braces allows you to use it next to other letters, but in this case there are punctuation separators so it doesn't matter Commented Sep 20, 2022 at 21:32

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.