Reputation: 121
I need a rule that will add an .html extension whenever there is 'not' a trailing slash.
A new client recently changed ecommerce scripts and the new version handles SEO differently and changed all of their 16,000+ product links. This was not caught prior to the site being re-indexed so we need to redirect the old to the new..
All products used to have links like this domain.com/category/productname but are now domain.com/category/productname.html
Category links did not change and all are like this domain.com/category/ (with trailing slash)
Upvotes: 12
Views: 36270
Reputation: 729
I think its the best way to go
RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^.]+?)/?$ %{REQUEST_URI}.html [L,R=302]
Upvotes: 0
Reputation: 51
There's a lot of answers here that sort of work, but by far the easiest way since apache 2.4 is to just enable MultiViews, see official docs https://httpd.apache.org/docs/2.4/content-negotiation.html
All I had to do was:
<Directory /var/www/html>
Options +MultiViews
</Directory>
This means that if I go to my site e.g. example.com/dashboard it just serves dashboard.html without needing any redirects, and it keeps the original URL as it was (so it doesn't append the extension).
I couldn't really find specifics in the docs about which file extensions get priority, so not sure what happens if you have both dashboard.html and dashboard.php living in the directory, or whether it's easy to change the priority order.
Upvotes: 2
Reputation: 11
The above solutions did not work for me,
I found a working solution at:
http://www.garron.me/bits/add-html-extension-nginx-apache-htaccess.html
At the .htaccess
section.
RewriteCond %{REQUEST_URI} !^.*\.html$ RewriteCond
%{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ $1.html [L,R=301]
Upvotes: 1
Reputation: 8559
to make sure X.html actually exists before rewriting to it:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ %{REQUEST_FILENAME}.html
!-f
file does not exist as requested!-d
directory does not exist as requested-f
requested file with '.html' extension does existUpvotes: 5
Reputation: 198
My solution for nginx:
forcing .html extension
if ($request_filename !~ ^.+(.html|\/)$) {
return 301 $scheme://$host$request_uri.html;
}
Upvotes: 1
Reputation: 785128
This is old thread but it is still worth posting a working/tested answer for this problem:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+?)/?$ /$1.html [L,R=302]
Skipped RewriteCond %{REQUEST_FILENAME} !-f
condition since regex pattern is not matching any URI with dot in it.
Upvotes: 4
Reputation: 31
The answer from @paul.grov.es seemed to work fine for me, but then I noticed that my javascript wasn't working anymore.
The solution is obvious, and mentioned by him: a '.html' was being added to the url, given that the javascript extension's only have 2 chars.
So, my solution turned out to be:
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.[a-zA-Z0-9]{2,4}
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1.html
Upvotes: 3
Reputation: 7196
This option is similar to @remco's, but doesn't require the use of [R] (an "external" redirect sent back to the brower). I also added a missing \ in the first condition:
Options FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI} !^.*\.html$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ %{REQUEST_FILENAME}.html
Upvotes: 9
Reputation: 4051
The answer from @david-wolever redirects everything that does not end in .html (or the root) to the same URL with an added .html extension, meaning it appends a .html extension to things like CSS and JavaScripts files, e.g. it will redirect /style.css to /style.css.html which is not likely what you want. It also has the spaces after ! character which will likely caused @greggles 500s
This redirects URLs which do not end in a dot followed by 3 or 4 alphanumeric characters:
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.[a-zA-Z0-9]{3,4}
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1.html
Or for finer grain control, whitelist the extensions you do not want .html appended to e.g.
RewriteCond %{REQUEST_URI} !\.(html|css|js|less|jpg|png|gif)$
Upvotes: 17
Reputation: 154494
RewriteEngine On RewriteCond %{REQUEST_URI} ! \.html$ RewriteCond %{REQUEST_URI} ! /$ RewriteRule ^(.*)$ $1.html
You might want to throw an [R] in there, or something too. See docs: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule (search for "redirect|R").
Upvotes: 3