The most upvoted answer doesn't check whether the URL points to a directory, so you're going to get some mysterious 'not found' errors when it tries to append '.html' to a directory path. Easily fixed:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [L]
The first condition will only pass if the path does not point to a valid directory. The second will only pass if the path points to a valid file when the .html extension is added. If both conditions pass, the rewrite rule simply adds ‘.html’ to the filename.
Notice that we can just match the entire path with .*
. You can reject paths that contain a period character if you wish, but it's not really necessary since you've already checked that {REQUEST_FILENAME}.html
is a valid file. In any case, it is unnecessary to escape a period character when it's inside a character class. I know you see this [^\.]
everywhere, but the slash is redundant. [^.]
is how to write it and look like a regex pro.
This kind of redirect will be invisible to the user because, by default, mod_rewrite does the substitution internally, without informing the browser. If you wanted to do a permanent redirect, you would add the [R=301] flag at the end.
Alternatively, as Genus Amar said, you can just enable the Multiviews option on a per-directory basis by adding this Options Directive to the .htaccess file:
Options +MultiViews
It's worth adding that this will only work if the server administrator has enabled MultiViews with the AllowOverride Directive, and it won't allow you to perform additional redirects.
Neither of these solutions (on their own) will remove the .html
if it’s part of the requested URL. If you want to do that as well, see my answer to this question.