How to automatically add a trailing slash to an URL
After long and boring researchs on how to automatically add a trailing slash ( ‘/’ ) after my web sites’ addresses, I thought some people might enjoy sharing the results of this quest…
For those who would wonder the purpose in that, it’s once again about search engine optimization.
Indeed, for a search engine, http://www.webagency.com/name and http://www.webagency.com/name/ are not the same. This is inherited from a time where /name would be a file and /name/ a directory. Nothing by then was preventing a file and folder in the same place to share a name.
Today, we took the habit to use more clear and user-friendly URIs, and most of the time we make it so that http://www.webagency.com/name and http://www.webagency.com/name/ point toward the same page.
Once again, the risk is to end up with two pages being considered as dupes by the search engines, diluting the global weight of the page.
To avoid this, we will try to have a canonical page, and to have the other one point onto this one.
There is several ways to so so, the easiest probably being the use of the “canonical” attribute recently introduced by Google.
For reference, it is about using a <link rel=”canonical” href=”http://www.webagency.com/w3c.php?quality=high”> like tag in the <head> section of the page.
This way, several URLs will be allowed to point to this page, but Google will know that the address given in the href is the one to take into account.
Another method is to always redirect the visitor to the address we want to have as the main one.
This can be done at the page level (for example with php), but it is probably more fit to do it from the web server (Apache) or a .htaccess file.
We then have several tools at our disposal, related to mod_alias and mod_rewrite (make sur they are activated on your hosting platform before you begin experimenting! This is not always the case)
My experiments lead me from RewriteRule to RedirectMatch, and back to RewriteRule for a result that at last seemed satisfactory.
As a documentation, I suggest you visit Apache’s doc, particularily the following links :
http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritelog
With no further ado, here’s my solution :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_URI} (^/blog/.*)$ [NC]
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
RewriteRule ^.*$ index.php [NC,L]
Let’s take a closer look :
RewriteEngine On
We make sure the URL rewriting engine is on. If it is not available, we will usually get a 500 error.
We will then test various cases :
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_URI} (^/blog/.*)$ [NC]
RewriteRule ^.*$ - [NC,L]
If the link points to a non empty file (-s = sized file)
or
the link points to a symbolic link (-l = link)
or
the link points to a directory (-d = directory)
or the URI begins with /blog/ with no regard to case (NC = Not Case-sensitive)
then we will replace the URL with itself (-) and ignore the following rules (L = Last rule)
RewriteRule ^.*[^/]$ %{REQUEST_URI}/ [R=301,L]
If we are sill here, it means the previous conditions didn’t apply.
So we are not facing a file/link/directory nor a blog entry (that we put here as an example of a branch to exclude… Note that blogs like WordPress have their own URL rewriting engine).
We are therefore going to replace everything that doesn’t finish with a / ( described as ^.*[^/]$ using regular expressions ) with the requested address followed by a / ( %{REQUEST_URI}/ ) and make an external redirection on this address (R = Redirect, 301 = the error code we want to return ).
This will be our last rule (L = Last), in order for it not to be replaced by another one before it gets applied (this seems trivial, but I must have lost some hairs before I realised it!)
At last, within the frame of our customised URLs projects, we will usually send everything else toward index.php that will interpret it :
RewriteRule ^.*$ index.php [NC,L]
There may be better ways to proceeed. If that is the case, I’d be glad to find out about them.
Anyhow, feel free to leave a comment, it’s always appreciated
