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



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.
@sneha, do you have the text of the error? Check your apache error logs or possibly your system error log for more information.
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.
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.
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
RewriteMap directive can’t be used in .htaccess. The function has to be defined in HTTPD config and then called from .htaccess.
Regards.
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
Can anyone tell me how do that in httpd and call it from .htaccess?
Thanks
Thanks for the tip, works great.
That won’t work. I will test it again.
Thank you,
Netburn is right — you can check the documentation for RewriteMap, and it doesn’t work in .htaccess.
Can’t seem to get it to work either, any update on this?
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.
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
Thanks for this information. I really had this case problem with my some urls and finding every page and changing it became difficult.
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
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 ?
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! :(
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!
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…
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]
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
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…
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.
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 ….
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!
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?
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]
Thanks reegz. Your idea worked for me.
Thanks to Chris Abernethy too for posing this article.
Thanks! Actually used it the other way around, but it worked like a charm!
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!
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
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)
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.
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
Thank you ZANE!! Thanks SO MUCH!!
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)?