Force Lower-Case URLs with mod_rewrite

You may find yourself in a situation at some point where you need to ensure that all access to your site is done using lower-case only. This may be because of SEO (avoiding duplicate content), or perhaps you want to ensure that you can seamlessly move between case-sensitive/insensitive operating systems. If you are running a standard LAMP stack, you're in luck. Apache's mod_rewrite can be used to 301-redirect all incoming requests to their lower-case counterparts with just a few configuration directives.

10. Don't be Case Sensitive
Since URLs can accept both uppercase and lowercase characters, don't ever, ever allow any uppercase letters in your structure. If you have them now, 301 them to all-lowercase versions to help avoid confusion. If you have a lot of type-in traffic, you might even consider a 301 rule that sends any incorrect capitalization permutation to its rightful home.
http://www.seomoz.org/blog/11-best-practices-for-urls

It doesn't require much to rewrite URLs to lower-case, and the necessary configuration directives can be placed in either a virtualhost or .htaccess file. First, the RewriteEngine is enabled, and a custom RewriteMap called 'lc' is defined using the internal 'tolower' map. Next, a RewriteCond rule is used so that only URLs containing upper-case characters are rewritten. Finally, the actual RewriteRule is defined using the 'lc' RewriteMap that we just created to transform the captured URL to lower-case before 301-redirecting the user.

RewriteEngine On
RewriteMap  lc int:tolower
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule (.*) ${lc:$1} [R=301,L]

The following is the output from the RewriteLog that shows the processing for a request to /INDEX.PHP. Note that only a single upper-case letter needs to be present for the rewrite rule to be triggered. The log output clearly shows the rewrite rule being applied, the RewriteMap being referenced, and the 301 redirect taking place. The subsequent request for /index.php is also shown, where the rewrite condition does not match and the request is passed through.

init rewrite engine with requested uri /INDEX.PHP
applying pattern '(.*)' to uri '/INDEX.PHP'
RewriteCond: input='/INDEX.PHP' pattern='[A-Z]' => matched
map lookup OK: map=lc key=/index.php -> val=/index.php
rewrite '/INDEX.PHP' -> '/index.php'
explicitly forcing redirect with http://test/index.php
escaping http://test/index.php for redirect
redirect to http://test/index.php [REDIRECT/301]
init rewrite engine with requested uri /index.php
applying pattern '(.*)' to uri '/index.php'
RewriteCond: input='/index.php' pattern='[A-Z]' => not-matched
pass through /index.php

Comments

8 Responses to “Force Lower-Case URLs with mod_rewrite”

  1. sneha on November 13th, 2008 10:30 pm

    I tried the above and the moment i add
    RewriteMap lc int:tolower

    to my .htaccess, i get a internal server error. We are running Linux/apache/coldfusion. What could the reason be?
    Thanks.

  2. cabernet on November 14th, 2008 1:41 pm

    @sneha, do you have the text of the error? Check your apache error logs or possibly your system error log for more information.

  3. 500 ERROR on November 27th, 2008 10:04 am

    hello
    Thank you for sharing that.
    I add your code to my .htaccess, and i get 500 error.My host server is godaddy.com. Unix/apache...
    And i don't know how to check my error logs.
    Can you help me?
    Thank you.
    Greeting from china.

  4. cabernet on November 27th, 2008 12:40 pm

    Hmm. I did a quick search and found that a lot of people seem to have issues with mod_rewrite on GoDaddy... Without more information on the type of hosting plan that you have and the level of control you have over your Apache configuration, I'm not sure I can help... I would suggest starting here (http://tinyurl.com/59v3te) and opening a support ticket with GoDaddy if you are unable to resolve the issue.

  5. Prasad Cheruvannur on December 5th, 2008 5:09 am

    Even I get internal server error. My hosting is host-gator. But I think this is something to do with server permission.
    For me simple mode rewrite also not working on .htaccess

    Regards

  6. Netburn on December 28th, 2008 11:02 pm

    RewriteMap directive can't be used in .htaccess. The function has to be defined in HTTPD config and then called from .htaccess.

    Regards.

  7. Panchu on May 7th, 2009 6:11 am

    Hi Chris,
    Thanks for this wonderful post, but you have mentioned that we can use RewriteMap in .htaccess. That won't work.

    'Netburn' you are correct, I have tried this from httpd conf and it is worked for me

  8. Julian on May 22nd, 2009 4:20 pm

    Can anyone tell me how do that in httpd and call it from .htaccess?

    Thanks

Got something to say?