Skip to main content
Code Review

Return to Revisions

4 of 4
replaced http://stackoverflow.com/ with https://stackoverflow.com/

Canonicalize URLs for static website

I want to "canonicalize" URLs for my static (files and folders) website.

The 'Aims' describes what I want to accomplish. The 'Code' gives my current .htaccess.

Everything works right now, but I wonder if the code could be improved:

  • any changes for better performance?
  • can some rules be removed?
  • can some rules be merged?
  • can something be shortened?
  • are some explaining comments wrong?

In my .htaccess there shouldn't be anything else as what is described in 'Aims' and my examples. So if there should be something that has nothing to do with it, it is probably unneeded (if I don't miss an important part right now).

Aims

  • Strip the file ending .html (but keep all other endings).
  • if the file is index.html, strip "index", too, and don't keep a (folder) trailing slash
  • no trailing slashs for files or folders
  • if someone adds a trailing slash, redirect to variant without

Example 1

  • Physical file: example.com/foo/bar.html
  • Desired URL: example.com/foo/bar
  • URLs that should redirect (301) to desired URL:
  • example.com/foo/bar.html
  • example.com/foo/bar/

Example 2 (if index.html)

  • Physical file: example.com/foo/index.html
  • Desired URL: example.com/foo
  • URLs that should redirect (301) to desired URL:
  • example.com/foo/index.html
  • example.com/foo/index
  • example.com/foo/
  • example.com/foo.html

Example 3 (if non-HTML file)

  • Physical file: example.com/foo/bar.png
  • Desired URL: example.com/foo/bar.png (= same as physical)
  • URLs that should redirect (301) to desired URL:
  • none

Code (.htaccess)

# Turn MultiViews off. (MultiViews on causes /abc to go to /abc.ext.) 
Options +FollowSymLinks -MultiViews
# It stops DirectorySlash from being processed if mod_rewrite isn't. 
<IfModule mod_rewrite.c>
 # Disable mod_dir adding missing trailing slashes to directory requests.
 DirectorySlash Off
 
 RewriteEngine On
 
 # If it's a request to index(.html) 
 RewriteCond %{THE_REQUEST} \ /(.+/)?index(\.html)?(\?.*)?\ [NC]
 # Remove it. 
 RewriteRule ^(.+/)?index(\.html)?$ /%1 [R=301,L]
 # if request has a trailing slash
 RewriteCond %{REQUEST_URI} ^/(.*)/$
 # but it isn't a directory
 RewriteCond %{DOCUMENT_ROOT}/%1 !-d
 # and if the trailing slash is removed and a .html appended to the end, it IS a file
 RewriteCond %{DOCUMENT_ROOT}/%1.html -f
 # redirect without trailing slash
 RewriteRule ^ /%1 [L,R=301]
 # Add missing trailing slashes to directories if a matching .html does not exist. 
 # If it's a request to a directory. 
 RewriteCond %{REQUEST_FILENAME}/ -d
 # And a HTML file does not (!) exist.
 RewriteCond %{REQUEST_FILENAME}/index.html !-f
 # And there is not trailing slash redirect to add it. 
 RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L] 
 RewriteCond %{REQUEST_FILENAME} -d
 # And a HTML file exists.
 RewriteCond %{REQUEST_FILENAME}/index.html -f
 # And there is a trailing slash redirect to remove it. 
 RewriteRule ^(.*?)/$ /1ドル [R=301,L]
 RewriteCond %{REQUEST_FILENAME} -d
 # And a HTML file exists.
 RewriteCond %{REQUEST_FILENAME}/index.html -f
 # And there is no trailing slash show the index.html. 
 RewriteRule [^/]$ %{REQUEST_URI}/index.html [L]
 # Remove HTML extensions. 
 # If it's a request from a browser, not an internal request by Apache/mod_rewrite. 
 RewriteCond %{ENV:REDIRECT_STATUS} ^$
 # And the request has a HTML extension. Redirect to remove it. 
 RewriteRule ^(.+)\.html$ /1ドル [R=301,L]
 # If the request exists with a .html extension. 
 RewriteCond %{SCRIPT_FILENAME}.html -f
 # And there is no trailing slash, rewrite to add the .html extension. 
 RewriteRule [^/]$ %{REQUEST_URI}.html [QSA,L]
</IfModule>

(some parts of this file are by Jon Lin over at Stack Overflow)

unor
  • 2.7k
  • 15
  • 24
default

AltStyle によって変換されたページ (->オリジナル) /