How do I remove trailing slashes from a URL when using Apache's default directory index file?

I am using Apache to serve a blog which consists of static HTML files. Currently, the blog uses a pretty standard URL structure, like this:

/2010/03/21/my-awesome-blog-post/

which maps to the file

/2010/03/21/my-awesome-blog-post/index.html

using Apache's mod_dir.

I'd like to remove the trailing slash so that URLs like

/2010/03/21/my-awesome-blog-post

work in the same way (and don't get redirected). Is there a way to do that with Apache?

(Note that I want URLs with the trailing slash to continue to work, as well.)

(Further note: I saw something about Apache's DirectorySlash directive, but I don't think it does what I want … although I'm not sure about that.)


You could always use mod_rewrite to redirect the directory name without the trailing slash to dirname/index.html. You could use RedirectConds to make sure that redirection doesn't get done if the URL ends with a trailing slash or with .html, and that it only applies specifically to blog post URLs.

Let me whip up an example, this'll take a moment.

# Trailing slashes and .html suffix
RewriteCond !/$
RewriteCond !\.html$

# Check if it's actually a dir and if index.html exists
RewriteCond %{REQUEST_URI} -d
RewriteCond %{REQUEST_URI}/index.html -f

# Rewrite anything that gets through (Probably insecure, but you get the idea)
RewriteRule ^(.*)$ $1/index.html

Edit: Can also be combined with Matt's solution of adding the redirect error code to the RewriteRule. It should probably also be made the last RedirectRule. Refer to the mod_rewrite documentation for more.


The Apache Rewrite Guide has a chapter on the "Trailing Slash Problem" (scroll down a bit) explaining how to solve the issue with the trailing slashes in general.

However, they also state that the trailing slash is required for directories when the rendered page in it uses resources (images, stylesheets, ..) with relative links - which will not work without the slash:

"The solution to this subtle problem is to let the server add the trailing slash automatically. To do this correctly we have to use an external redirect, so the browser correctly requests subsequent images etc. If we only did a internal rewrite, this would only work for the directory page, but would go wrong when any images are included into this page with relative URLs, because the browser would request an in-lined object. For instance, a request for image.gif in /~quux/foo/index.html would become /~quux/image.gif without the external redirect!"


Did you read the definition of the DirectorySlash?

The DirectorySlash directive determines, whether mod_dir should fixup URLs pointing to a directory or not.

Typically if a user requests a resource without a trailing slash, which points to a directory, mod_dir redirects him to the same resource, but with trailing slash for some good reasons:

  • The user is finally requesting the canonical URL of the resource
  • mod_autoindex works correctly. Since it doesn't emit the path in the link, it would point to the wrong path.
  • DirectoryIndex will be evaluated only for directories requested with trailing slash.
  • Relative URL references inside html pages will work correctly.

Well, if you don't want this effect and the reasons above don't apply to you, you can turn off the redirect with:

# see security warning below!
<Location /some/path>
DirectorySlash Off
SetHandler some-handler
</Location>

Removing index.php from URL can be done by writing only two lines in your .htaccess (mod_rewrite in Apache) file. Before writing the rules in .htaccess, make sure that mod_rewrite is enabled (RewriteEngine On) in your Apache server. Most probably mod_rewrite is enabled in a Linux server, but for a windows server you might need to contact the hosting people to enable mod_rewrite. You can check this by looking in phpinfo().

Below are the rules which will remove index.php from the URL:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9} /([^/]+/)*index.php HTTP/ 
RewriteRule ^(([^/]+/)*)index.php$ http://www.%{HTTP_HOST}/ [R=301,NS,L]

Redirect 301 means "Moved Permanently" so most search engines will remove index.php from the URL.