I'm serving a static HTML site with Nginx using the following configuration:
server {
# some configs
# Web root and file handling
location / {
root /var/lib/jenkins/workspace/test;
index index.html index.htm;
try_files $uri $uri.html $uri/ /index.html;
}
}
I want to remove .html
from the URLs, so I added this rewrite rule:
location ~ ^/(.*)\.html$ {
rewrite ^/(.*)\.html$ /$1 permanent;
}
This works fine for pages like /test.html
, which are rewritten to /test
. However, whenever I access the root URL /
, the browser displays /index
in the address bar, which is not what I want. I want the root URL to remain as /
.
How can I prevent /index
from being appended to the root URL while keeping the .html
rewrite for other pages?
This occurs because the index
nginx directive performs an internal redirect when it locates an index file, as explained in the documentation:
It should be noted that using an index file causes an internal redirect, and the request can be processed in a different location. For example, with the following configuration:
location = / { index index.html; } location / { ... }
a
/
request will actually be processed in the second location as/index.html
.
The internal redirect from the root URL /
to /index.html
results in the request being processed by your regex location, which then returns an HTTP 301 redirect to the /index
URL. To prevent this behavior, the simplest solution is to define a separate location specifically for the /index.html
request:
location = /index.html {
root /var/lib/jenkins/workspace/test;
}
A more advanced solution involves modifying your regex to exclude any index.html
file, regardless of its level in a nested subdirectory structure:
location ~ ^(?<path>.*/(?!index\.html$)[^/]*)\.html$ {
rewrite ^ $path permanent;
}