I'm trying to remove the .html from my landing page, an example would be instead of domain.com/contact.html it would be domain.com/contact while at the same time keeping the .html for all the folders within the website, so domain.com/components/file.html would stay as a .html..

So in other words redirect for the landing page, but not for all the other files on my server..

This is the code I'm currently using to remove the .html but it also removes it for all the other directories as well.

#example.com/page will display the contents of example.com/page.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]

#301 from example.com/page.html to example.com/page
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/
RewriteRule ^(.*)\.html$ /$1 [R=301,L]

Would anyone have any advice on this matter?


2 Answers 2


Never mind, I found the solution:

DirectorySlash Off
RewriteEngine On

RewriteCond %{THE_REQUEST} \s/+(.*?/)?(?:index)?(.*?)\.html[\s?/] [NC]
RewriteRule ^(.[^\/]*)$ /%1%2 [R=302,L,NE]

RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)  /$1.html [L]
#301 from example.com/page.html to example.com/page
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/
RewriteRule ^(.*)\.html$ /$1 [R=301,L]

Let's focus on this one, as the one you want to change. Firstly I would say the THE_REQUEST is just adding complication. I guess its purpose is to 'stop' the rule adding the html back, removed during the first 'internal' redirect.

... I would suggest that it's much better just to 'fix' that by putting the URL first. ie. have the 301 removing the extension FIRST. (It has L in it anyway.) Then have the internal redirect.

Then it seems you just need

RewriteRule ^([^/]+)\.html$ /$1 [R=301,L]

[^/] means match anything except a slash. So then paths with a slash in them (eg folders!) won't match.

You may also want to consider adding:

RewriteBase /

to the beginning of the file to make sure that relative paths work. ie that the rewrite rule isn't matching a path that already has slashes at start.

Alternatively use:

RewriteRule ^/?([^/]+)\.html$ /$1 [R=301,L]
  • The check against THE_REQUEST is still required in a per-directory (.htaccess) context in order to prevent a redirect loop (as you suggest). Simply changing the order of these directives is not sufficient. The L flag simply stops the current round of processing, the rewriting process then effectively starts over. (This is in .htaccess, as opposed to the server config.) Also, the RewriteBase directive does not affect what is matched, as you seem to imply. RewriteBase only overrides the directory-prefix that is added back on relative path substitutions.
    – MrWhite
    Sep 29, 2017 at 12:12

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.