Use .htaccess to rewrite/redirect requests

How to redirect or rewrite URLs using .htaccess?

File, called as .htaccess, can be used to rewrite URLs apart from doing other stuffs like application handlers etc.

We can do some potent manipulations with our links, like,

  • Transforming long URL’s into short, easy to remember URLs
  • Transforming URLs having in-comprehensive query strings like “filename?id=carnivores&cat=animals” into human readable URLs like “livingthings/animals/carnivores”
  • Redirect missing pages. Instead of showing frustrating messages like “401 Page Not Found” you can show your users a neat html pages showing a humble message like “Your request seems to be having wrong structure. Please check your URL“. Or “We are under maintenance. Please be back after some time“.
  • Preventing hot-linking. Hot linking is, a third party using your servers bandwidth to access some stuff from your server directly eg images, css, javascript etc.
  • Performing automatic language translation (keeping all language files under one directory), etc.

Lets start writing our .htaccess file. We should put two lines (Options +FollowSymlinks and RewriteEngine on) in almost all .htaccess files to start the writing engine (details out of scope). I will skip these two lines in my examples, please remember to have them in your file. The third line specifies which directory to start from (make base directory). Note: In case you are putting htaccess file in some sub directory then RewriteBase should be written to point to that sub-directory else rewritten URLs (targets) will be relative to home directory of the domain.

1) How to rewrite to

Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ $1.php

Forward slash (/) here means home directory of (usually public_html)

Therefore our rewrite rules would match only filenames & paths which are just after (here somefile.html)

^, (.*), $ and $1 are all regular expression special characters having special meaning e.g, ^ is to match the start of the string (it is start anchor), similarly $ is end anchor. Do not get confused with $1, it is not an anchor. It carries the back-referenced data captured with the parentheses “(” and “)”. A dot “.” matches any character and an asterisk following this dot means zero or more characters. A dot preceded by a back slash \. matches the literal dot (and not any character). For more info please refer regular expression tutorials.

2) How to rewrite all language files to a language directory, say, to

RewriteRule ^(.*)\.html$ french/$1.html

3) How to permanently redirect old URLs to new ones (to secure old page ranks)

RewriteCond %{HTTP_HOST} ^olddomain\.com$ [NC]
RewriteRule ^(.*)$$1 [R=301,L]

Here [NC] refers to case insensitive match and R=301 gives the HTTP Response to the client as “Permanently moved” to new URL.

It will tell crawlers not to discard old URLs from their index and drop the page rank rather replace old ones with new ones.


Redirect permanent /oldhtmlfile.htm

This way we can either strip www. from our domain (or add it, if you want) to put away ambiguity (between and for crawlers and maintain a uniform linkage with external websites. For crawlers both are different entities.

To strip www.

RewriteCond %{HTTP_HOST} ^www\.mydomain\.com
RewriteRule ^(.*)$$1 [R=permanent,L]

To add www.

RewriteCond %{HTTP_HOST} ^mydomain\.com
RewriteRule ^(.*)$$1 [R=permanent,L]

Note: Moved permanently response code can also be served using PHP but that is not as good as doing by .htaccess file.

Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location:" );

4) How to catch query strings (?var=value&var2=value2 etc) to readable ones, say, to

RewriteCond %{QUERY_STRING} cat=(.*)
RewriteRule ^file.php.* /file.php/category/%1 [R]

This can be used to redirect (not only rewrite) a user to readable URL. [R] handles redirection. %{QUERY_STRING} a global variable, contains the whole query string. This can be used to support some old URL patterns (backward compatibility). Though the reverse of it would be used to show and store the human readable URLs while at server you still process them with old functionality, eg. your users remember and write URL like file/category/carnivores while you still process them with file.php?id=123

RewriteRule ^file/catogory/canivores/ file.php?id=123

Stop hotlinking of your images with,

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?host\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(jpe?g|gif|bmp|png)$ [L]

%{HTTP_REFERER} contains the name of the refereeing website (eg [NC] means case insensitive match, [L] means last (end up) the conditions rule here (to start another brand new rule, in case).

5) You can create some Not found error message pages.

ErrorDocument 401 /my-401-page.php

In this case if anybody requests a page which is not there on the server, s/he would be presented my-401-page.php, which can do some logging task also.

6) Limit the number of simultaneous connections to a directory or whole website (homepage) by,

MaxClients 100

7) In case of error, you can show your users an email of system administrator

How to debug rewrite rules in htaccess file?

a) Mostly, the problem could be that AllowOverride is not set to allow configuration directives.

You should make sure an AllowOverride None is not in effect for the file scope in question by putting garbage in your .htaccess file and reload. If a server error is not generated, then you almost certainly have AllowOverride None in effect.

b) Check the apache error log file (check through cpanel) at the sever.

c) Use the [R] option (which redirects the browser) to redirect the rewritten URL into the browser’s address bar. This URL can be appended with the matched back-references. Hence we get the regular expression matched strings in URLs e.g.,

RewriteEngine On
RewriteRule ^(.*)$ /file.php/category/match=$1 [R]

It will paste /file.php/category/match=”matched value here” in the address bar.

d) Close all instances of the browser while debugging.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>