Scott
Scott

Reputation: 121

ReWrite rule to add .html extension

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

Answers (10)

Ijaz Ahmed Bhatti
Ijaz Ahmed Bhatti

Reputation: 729

I think its the best way to go

RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^.]+?)/?$ %{REQUEST_URI}.html [L,R=302]

Upvotes: 0

Joren Broekema
Joren Broekema

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

remco
remco

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

oriadam
oriadam

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
  • condition !-f file does not exist as requested
  • condition !-d directory does not exist as requested
  • condition -f requested file with '.html' extension does exist

Upvotes: 5

vgrinko
vgrinko

Reputation: 198

My solution for nginx:

forcing .html extension

if ($request_filename !~ ^.+(.html|\/)$) {
    return 301 $scheme://$host$request_uri.html;
}

Upvotes: 1

anubhava
anubhava

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

bmareal
bmareal

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

Thomas Leonard
Thomas Leonard

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

Paul Groves
Paul Groves

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

David Wolever
David Wolever

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

Related Questions