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
Chris Abernethy
PHP Wrangler, MySQL DBA, Linux SysAdmin and all around computer guy, developing LAMP applications since Slackware came on 10 floppy disks.

41 Comments on "Force Lower-Case URLs with mod_rewrite"

  1. sneha says:

    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 says:

    @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 says:

    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 says:

    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. 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 says:

    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 says:

    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 says:

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

    Thanks

  9. traphic says:

    Thanks for the tip, works great.

  10. That won’t work. I will test it again.
    Thank you,

  11. Nabha says:

    Netburn is right — you can check the documentation for RewriteMap, and it doesn’t work in .htaccess.

  12. Rain says:

    Can’t seem to get it to work either, any update on this?

  13. Admin says:

    The line:
    RewriteMap lc int:tolower
    has to go in httpd.conf.

    The rest goes in .htaccess and it works fine.

    If you dont have access to httpd.conf, ask you host and maybe they will add it for you.

  14. reegz says:

    The above code will not work with all setups particularly if you are using the Zend libraries and must deal with this, as Zend’s routing is case insensitive. Below I have included code that should work for all Apache 2.x setups.

    This must be added to your virtual host below your vhost directives and above the directory permissions.

    # all of your vhost directives here

    #used to force lowercase URI’s to avoid duplicate pages
    RewriteEngine On
    RewriteMap lowercase int:tolower
    RewriteCond $1 [A-Z]
    RewriteRule ^/(.*)$ /${lowercase:$1} [R=303,L]

    #directory permissions

    Options Indexes Includes FollowSymLinks ExecCGI MultiViews
    AllowOverride All
    Order allow,deny
    Allow from All
    Deny from None

  15. Thanks for this information. I really had this case problem with my some urls and finding every page and changing it became difficult.

  16. Manish says:

    Hi,
    Thanks for sharing the information,
    I tried above and succeeded.

    But i have scenario, my Webserever is Apache and on Linux.

    My Document Root May contain both lower and upper case files (as linux is not case sensitive).

    Pl. suggest, what to do if i have to serve both type file (upper and Lower case files),

    I do not want to use NC as it Duplicate the Contents (URL) in Searches or whatever….

    Pl. suggest some solution for this…

    Regards
    Manish Singh

  17. This article is great, i also read the link you posted on seomoz.com the tips they give are very usefuls and logicals !

    I can’t use your solution because i only have access to the .htaccess file, do you have any other solution ?

  18. Big Fan says:

    to reegz
    thank you for your post. Is your fix intended to also redirect links that have capital letters to small letters? i implemented your solutions and I still can’t. The page with capital letters doesn’t still shows that it has not been directed when I enter it in this page: http://www.seoconsultants.com/tools/check-server-headers-tool/#Report
    There are no errors either on the log. Any ideas? I am desperate! :(

  19. Big Fan says:

    I have figured it out!
    The solution was working for me the whole time.

    all I had to do was clearing the cache on my machine to make the pages load fine. Get this, I was not able to even call pages that I have not before.
    I was going nut. Luckily, after I figured it out, I had to do it for other sites, so I did a screen recording of the behavior and the fix (the clearing of all files/cache and cookies). i was able to replicate the issue, the fix over and over again!

  20. rachmat says:

    in my google webmaster tools, say Duplicate title tags 24 pages .. I suggested to this site, can you help me, what this mean and what should I do? thanks…

  21. rubycat says:

    I had to alter the htaccess rewriterule a little in order to get it to work–otherwise, it rewrote to the absolulte server path. If this helps anyone else…

    First, as stated above, this line goes in httpd.conf:
    RewriteMap lc int:tolower

    This goes in htaccess:

    # used in conjunction with rewritemap in httpd.conf for forcing lowercase
    RewriteCond %{REQUEST_URI} [A-Z]
    RewriteRule ^[\/]*(.*)$ /${lc:$1} [R=301,L]

  22. Eric says:

    RewriteMap not running in share hosting. i don’t have permission to edit http.conf. when i use RewriteMap , server have error to config. How can i use http.conf to use this config.
    Thanks

  23. Hellas says:

    It does not work on your site.

    Try
    http://www.chrisabernethy.com/force-Lower-case-urls-with-mod_rewrite/

    with capital L and its not redirecting…

  24. MG says:

    Thanks for the info.

    If URLs have parameters, will this code force the parameters and their values to lowercase as well, or will just the part of the URL up to the ‘?’ be converted to lowercase?

    Ideally, in my client’s situation, they’d like for parameters and their values to remain in their current case (whether upper or lower) and only force the part of the URL up to the ‘?’ to lowercase (mainly because they have a ton of AdWords tracking codes with some uppercase letters and would prefer to keep it that way). If anyone knows how to revise the code accordingly, that would be most appreciated.

    Thank you.

  25. jac says:

    I am also stuck with this url re-write. I want to pull my hairs now.
    I am doing re-write in httpd.conf file.

    but there are 3-5 level of urls, and I don’t know how to arrange them. I put the 5th level url on top but still some how it goes to zero level url. i.e. http://www.example.com/abc-def.html

    any solution ….

  26. Randy says:

    If you are on a shared server such as HostGator (my case), they will not be able to change the httpd.conf file for you. Instead, you are going to have to use a php script for a redirect from upper to lower URLs. My site is hosted at HostGator and the php script redirect works great!

  27. Optwizard says:

    If the site i am trying to fix all the urls on the server are /Site-Link would the redirect or force lowercase work for this?

  28. Mark says:

    Thanks for the info, that works for me like a charm, however, we have many images that folks entered into our CMS with various iterations of camel casing. Is there anyway to supplement this code to exclude the rewrite for jpg & gif?

    We tried the following with no luck.

    # Rewrite URLs to transform the URL to lower-case before 301-redirecting the user
    RewriteEngine on
    RewriteMap lc int:tolower
    RewriteCond %{REQUEST_URI} !.*\.(jpg|gif)
    RewriteCond %{REQUEST_URI} [A-Z]
    RewriteRule (.*) ${lc:$1} [R=301,L]

  29. Murugavel says:

    Thanks reegz. Your idea worked for me.

    Thanks to Chris Abernethy too for posing this article.

  30. bplayer says:

    Thanks! Actually used it the other way around, but it worked like a charm!

  31. Scriptster says:

    Most servers would not allow defining RewriteMap in the context of .htaccess file (i.e. per directory). You will see error messages like these : RewriteMap not allowed here
    You can definitely use an already defined Rewritemap in the .htaccess file but you have to define it in the server’s config file first: /etc/httpd/conf/httpd.conf

    So, this great tip has to be split into two steps:

    RewriteMap lc int:tolower – goes to httpd.conf
    RewriteRule (.*) ${lc:$1} [R=301,L] – goes to .htaccess

    Cheers!

  32. ZANE says:

    For shared servers which don’t have the rights to either change .httpd.conf or to use virtual host, there is another way to find resources independent of case:

    Options +FollowSymlinks
    RewriteEngine On
    CheckSpelling On
    CheckCaseOnly On

  33. 411LTD says:

    Thank you ZANE!! Thanks SO MUCH!!
    Your recommendation worked like a freaking charm ;-D))

    (note to others who are struggling to learn, add the code from ZANE’s above comment into your .htaccess file)

  34. Vlad says:

    This is VERY BAD to suggest to convert all URI to lowercase. If you are trying to use mcrypt or some other Base64 style encryption, case sensitivity is an IMPORTANT issue. Not to mention Linux compatibility, etc. Really stupid idea dude.

  35. dgswilson says:

    Zane, The best things in life are eeezy – Thanks, that should take care of about 50 not founds a month from those sites with malformed links pointed at me

  36. Thank you ZANE!! Thanks SO MUCH!!

  37. Leona D says:

    This works great! Except… Now I have files (PDFs, images files, etc.) that 404 because some of the filenames have uppercase letters in them. Any idea how to do this for all URLs except a subset (for example: all URLs except those that end in .pdf, .jpg, .doc)?

Trackbacks for this post

  1. .htaccess:How to convert and redirect url in uppercase to lowercase?
  2. Перевод URL в нижний регистр через .htaccess - Aramaki OnLine
  3. Convert and redirect URL in uppercase to lowercase using .htaccess - Admins Goodies
  4. Force Lower-Case URLs with mod_rewrite : Chris Abernethy . com | Local Internet Marketing New Port Beach CA

Got something to say? Go for it!