Ultimate Guide to htaccess and mod_rewrite

  • 2
  • July 14, 2007

Often described as “voodoo” by frustrated webmasters the use of mod_rewrite and htaccess files is one of the more advanced tasks a web developer has to face.

The good news is that unless you are looking for really advanced solutions you don’t have to fully understand how they work to use them on your website. Most of the htaccess and mod_rewrite tips on this page can simply be cut and pasted into a text file and uploaded to your server.

Over the last few years I’ve given the same htaccess tips to hundreds of webmasters so I decided to create a page with all the common uses.

htaccess is a configuration file that controls Apache web servers, mod_rewrite is a rewrite engine used by web servers to modify urls before they load.

The htaccess file is a text file called .htaccess – htaccess is the file extension, there is no filename. Normally it resides in the main root directory on your server but you can also create individual htaccess files for different directories on your site.


The easiest htaccess trick is to make sure that your site doesn’t have any canonicalization issues on the homepage.

A lot of websites suffer from poor search engine rankings by having a number of different versions of the homepage, for example:


These pages are all seen as different urls, despite them having exactly the same content in most cases. Google has got better at deciding which version to use over the past 12 months but you can still run into problems.

To solve this issue simply add the following to your htaccess file:

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^yoursite.com
RewriteRule (.*) http://www.yoursite.com/$1 [R=301,L] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9} /index.html HTTP/
RewriteRule ^index.html$ http://www.yoursite.com/ [R=301,L]

This will redirect all versions to http://www.yoursite.com

Changing html files to php

Sometimes you might have a static html website and need to use php code on the html pages. Rather than redirecting all your html pages to the equivalent php versions you simply need to tell your server to parse html files as if they were php.

AddHandler application/x-httpd-php .html

This works with any files so if you want to create dynamic xml or asp files that behave like php files you simply edit the code as required:

AddHandler application/x-httpd-php .xml
AddHandler application/x-httpd-php .asp

Error pages

Custom error pages can be set up in cpanel fairly easily, if you want to create a custom error page in htaccess instead use this line:

ErrorDocument 404 http://www.yoursite.com/404.php

Directory Indexes

To avoid Google indexing your directory indexes you might need to specify an index page for your directories. This is not required on some servers.

DirectoryIndex index.php3

My preference is to redirect the directory index page to either the homepage or another suitable page. For example www.yoursite.com/images/ can normally be redirected to www.yoursite.com and www.yoursite.com/forum/ can normally be redirected to www.yoursite.com/forum/index.php

Redirecting pages

A nice simple use of htaccess is to redirect one page to another:

redirect 301 /old-page.php http://www.yoursite.com/new-page.php

Sending your feed to Feedburner

If you want to switch your feed to the Feedburner service you will need to redirect your current feed to the new http://feeds.feedburner.com/yourfeed location.

The redirect needs to apply to all users except the Feedburner spider:

RewriteCond %{HTTP_USER_AGENT} !FeedBurner
RewriteRule ^your-feed.xml$ http://feeds.feedburner.com/your-feed [R,L]

Advanced hotlink protection

If you want to block other websites from hotlinking your images, but allow indexing of your images in the Google, Yahoo and MSN image search engines, you should use the code below:

RewriteEngine on
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^http://([^.]+.)?yoursite. [NC] RewriteCond %{HTTP_REFERER} !google. [NC] RewriteCond %{HTTP_REFERER} !search?q=cache [NC] RewriteCond %{HTTP_REFERER} !msn. [NC] RewriteCond %{HTTP_REFERER} !yahoo. [NC] RewriteCond %{REQUEST_URI} !^/hotlinker.gif$
RewriteRule .(gif|jpg|png)$ /hotlinker.gif [NC,L]

The hotlinker.gif image is a custom image that you have created. I suggest using something like “This image was hotlinked from www.yoursite.com” and your logo.

My personal preference is to allow hotlinking but to implement a solution to make use of Google Images and hotlinkers to build links to your site.

Create beautiful url’s with mod_rewrite

The Apache rewrite engine is mainly used to turn dynamic url’s such as www.yoursite.com/product.php?id=123 into static and user friendly url’s such as www.yoursite.com/product/123

RewriteEngine on
RewriteRule ^product/([^/.]+)/?$ product.php?id=$1 [L]

Another example, rewrite from:

www.yoursite.com/script.php?product=123 to www.yoursite.com/cat/product/123/

RewriteRule cat/(.*)/(.*)/$ /script.php?$1=$2

Removing query strings

Some websites like to link to you by adding an query string, for example I could link to www.yoursite.com/index.php?source=blogstorm just so you know where your traffic came from. This creates duplicate content issue for your site so you really need to redirect back to your homepage:

RewriteCond %{QUERY_STRING} ^source= RewriteRule (.*) /$1? [R=301,L]

Further reading:

If you have any questions please post in the comments.

Patrick Altoft

About Patrick Altoft

Patrick is the Director of Strategy at Branded3 and has spent the last 11 years working on the SEO strategies of some of the UK's largest brands. Patrick’s SEO knowledge and experience is highly regarded by many, and he’s regularly invited to speak at the world’s biggest search conferences and events.

  • http://livelydirectory.com Richie

    You’ve some great tips there,thanks Patrick!

  • http://noodleinvite.com.au Free SMS Andy

    Fantastic guide! You’ve made everything seem so simple. As you mentioned, htaccess has always been ‘voodoo’ for me

  • http://higadattack.blogspot.com othello

    simple, elegant but rocks!

  • dew

    eh, it’s still pretty voodoo to me, even after reading lots of places, i still don’t seem to get it.

    I’m trying to take something like
    but make it really go to:

    and I have about 10 of those pages, each with different names like page2.php and page3.php. so I would need a rule for each one i think, but I just can’t seem to get it to work how I need… any suggestions or help?

  • http://vanderlust.com TE

    Excellent advice – thanks.

    One thing I cant fathom tho:

    I have http://www.example.eu pointing to the same name servers as my main site at http://www.example.com

    How would I write into the htaccess for anything coming to the .eu site to be rewritten to the .com site so as to avoid dupe issues?


  • youngus

    thnx for all these. Smile have a little problem with my site. The situation is: I have LoadModule rewrite_module modules/mod_rewrite.so
    in my httpd.conf,
    the DocumentRoot is “/var/www/html”, and my site is under the html directory, that means /var/www/html/mysite/,
    I put .htaccess file these directives:
    php_value error_reporting 7
    RewriteEngine On
    RewriteBase /
    Options +FollowSymlinks
    RewriteRule ^([0-9]+)/(.*)?$ /index.php?module=item&action=show_item_decr&item_id=$1

    but it seems that it doesn’t work ! it gives me a 404 page, and even if I put one of your directives it doesn’t work , can you help please ! is there anything I have to add ! thnx !

  • http://dogiee.com Benjamin

    When I use
    RewriteCond %{QUERY_STRING} ^source= RewriteRule (.*) /$1? [R=301,L]

    I get a 500 server error.

    Am I not using it right?

  • http://sentoguide.com Wouter

    Thanks for the useful tips!

  • http://www.davidairey.com David Airey

    Cheers Patrick. I’ll mention this article on my latest blog post.

  • Pingback: How to stop image hotlinking and bandwidth theft | David Airey :: Graphic and Logo Designer()

  • http://www.ladadadada.net/articles/apache_regex_guide Dave

    dew: eh, it’s still pretty voodoo to me, even after reading lots of places, i still don’t seem to get it.

    Apache mod_rewrite IS voodoo. That’s why it seems like voodoo to you.

    It even says so in the official documentation. (Although they removed that quote from the 2.0 docs, mod_rewrite is still the same, and still voodoo.)

  • http://tamugaia.com Josh

    Very good tips. I spent one whole morning on .htaccess and got it done only when I found this article.

  • http://www.askapache.com AskApache

    You might enjoy checking out the .htaccess guides here too.

    Nice and simple tutorial, thanks!

  • http://www.beauty-salon-marketing.co.uk Jon

    Thanks for the tutorial, Patrick

    I used it to redirect an old static site to a WordPress site. I discovered some extra bits along the way that might be useful –

    – If you’re using WP permalinks, WP adds some lines to htaccess. make sure you put additional stuff outside the code block that WP adds. Otherwise it may get overwritten next time WP writes to htaccess.

    – Put your redirects before the code that WP adds, so that they are processed before control is passed to WP

    – If there are spaces in the old URLs, put quotes around them. Eg.
    redirect 301 "/old page.htm" http://www.mysite.com/newpage

    (NB. there is a WP plugin called “Redirection” but I wanted to learn about htaccess, and keep my list of plugins as short as possible!)

    Thanks for a great site, good to read a UK perpsective on SEO stuff!

    Cheers, Jon

  • http://www.jackiebrownmedical.ie Ian Wortley

    Wow… that’s a great artical. You have no idea how many different versions of rewrites I have crawled through…. none of them worked…. until yours. I am more than grateful!

    I have a question though. Windows live has indexed http://www.mysite.ie/?

    How or why I don’t know but I’d like to get rid of it. I have not got my head around regex yet and can’t work it out… I ended up with a loop when I tried to modify your QUERY_STRING source= (which was absolutely ideal for getting rid of my index.php?url=home problem.. Thanks again).

    While I owe you big time already I’d appreciate any help you could offer with this… be it a solution or where to look for one… I’m stumped!

    You have my site address and email address should you need them.

    Thanks again for your brilliant page.

    • http://www.blogstorm.co.uk Patrick Altoft

      I suggest just redirecting it in your domain registrar control panel rather than using htaccess.

  • http://srganesan.wordpress.com ganesan

    hi mr Patrick Altoft,
    Thank you i am new to htaccess. Very help ful for your wonderful tips

  • http://www.vacation-rental-wonderland.com/ Craig Mullins

    Great info. One issue with the Canonicalization script. The url’s and directory’s should end with a trailing slash.


    It will save an extra query on your web server and make it just a tad faster.

    Let me know if you modify that, so I can ad it to my htaccess file.

  • Pingback: SEO Mod Rewrite | Search Engine Optimisation (SEO) Feed from Position Gold Ltd()

  • http://www.reddinet.co.uk redditch

    Thanks for the tips I’m still struggling with some rewriting but i’m certainly getting better!

  • http://wa2n.staff.uns.ac.id/en/ wa2n

    good article

  • http://www.vietwave.com Dat Hoang

    Very useful tutorial! It’s easy to learn how to make clean and nice urls. Thank you for your tutorial, Patrick Altoft.

  • http://www.lukefretwell.co.uk Luke Fretwell

    I am trying to optimise my football team’s website. The player profile pages url is:
    I managed to write the a rule so if you type /player-lukefretwell you will go to /players.php?player=lukefretwell while keeping /player-lukefretwell.
    But I also want it so that if you type /players.php?player=lukefretwell the address bar changes to /player-lukefretwell and still go to /players.php?player=lukefretwell

    My reason for wanting to do this is that I am worried that google will index both types of url, then this would dilute the pages and also flag up duplicate content.

    Am I wrong in understanding that the two can both be indexed. If I am right to worry is it possible to do a rule to just rewrite what is seen in the address bar?

    • http://www.blogstorm.co.uk Patrick Altoft

      Luke you do need to write a rule to redirect. If you can’t figure it out in htaccess then create a copy of players.php and call it players2.php and use this as the script to generate your /player-lukefretwell pages. Now change your players.php to use a php redirect at the top which points to /player-$player

  • http://downloadic.blogspot.com Thecastex

    Nice tutorial. Very simple for me, thanks…

  • http://seogadget.co.uk/ richardbaxterseo

    Solid write up and extremely useful. Thanks Patrick!

  • pjbyrnes

    I have been banging my head against the wall to do what I believe is a simple task. My client need me to simplify a url:


    I don’t need it to automate for the entire site and I cannot afford to have the php code rewritten. I am happy to add a string to the .htaccess for each url I need changed. Is this difficult to do? It is not a redirect because http://hhhh/saccny/Board_of_Directors does not really exist.

  • http://www.sandiegowebstudio.com sandiegowebdesigner

    I’ve also read that google treats domains with a trailing slash (ie, http://domain.com/ and http://domain.com ) as two different websites, as well as http://www.domain.com/ and http://www.domain.com WITHOUT the trailing slash,so there’s even more url bleeding?

  • Pingback: Easy Clean URLs with Apache’s mod_rewrite « Junaid Bhura()

  • jeff

    Hi there,

    If I do a mod rewrite do I then need to do a 301 redirect to so there is no duplicate content?

    Thanks in advance.


  • http://www.vietnamdhtravel.com TONY DUNG

    Help me to create file .HTACCESS for apache (php website) for
    Thank you so much

  • http://www.jintudesigns.com Jintu

    Thanks for making these so easy.

  • Paras

    Hi Patrick… After reading this and other articles on net I am able to
    redirect pages http://www.asd.com/case/20-2040 to pages like http://www.asd.com/xyz.php
    RewriteRule ^case/([0-9]{2})-([0-9]{4}) xyz.php [NC]

    but what is happening is that it is not taking css .
    Further more if I am using
    RewriteRule ^case/([0-9]{2})-([0-9]{4}) http://www.asd.com/xyz.php [NC]
    It works fine but the url in address bar changes…..

    Can you solve my problem.thnx in advance

  • http://www.webshed.ie Ian Wortley

    Hi Paras, What is happening there is that your page is looking for the CSS in the wrong folder. You have redirected to a folder that is up a level. By changing the path of your CSS file to the root directory you should be able to fix it. This depends on the file structure of your hosting provider. Ask them for the path to your root directory.

    Alternatively you could try adding ../ before your path. The two dots signify going up a level in the directory.

    Hope that helps.


  • Pingback: 5 Aspectos básicos de SEO a optimizar en tu blog | Bloguismo()

  • Pingback: Inhoud van aangepaste map browsen in een Wordpress website()

  • http://gamil.com hey guys

    if all of u wanna mod_rewrite url
    u should change url internal link at ur php/script
    then modif ur htaccess


  • Pingback: MODE_REWRITE - TechFreekz()

  • http://kerrybullmore.com/blog Kerry Bullmore

    Hi Patrick
    Surfing the web certainly comes up trumps from time to time. I only recently discovered the power of htaccess and the addition of nofollow code to help prevent loosing link juice. I appreciate the depth of your post.

  • http://dailyhowtofix.com MMORPG Gamer

    Thanks! I was looking for a good hotlink protection.

  • http://www.justsearching.co.uk/ Andrew North

    Hi Guys,
    It still amazes me to this day just how much developers dislike working on mod_rewrites or htaccess files their is so much useful information regarding this stuff should make things straight forward.

    Great post Patrick

  • http://freeworkathomereview.com Jason

    I had to do this a couple of weeks ago while using FTP Core. This is the best way I have seen it explained for people yet. I am going to make a post on one of my sites linking back to this as there aren't a lot of people out there explaining it like you have. Thanks for the great info as always Pat.

  • http://www.sportinggoodsreview.co.uk/ Jeremy Owens

    I still don't understand why people would want to stop hot linking images. Isn't that this some kind of exposure to your web? I mean, if people in the forum talk about image that we post and they also point the source, wouldn't be great?

    • http://www.rawfunk.com.au Gaming SEO

      If I'm understanding you correctly, I personally don't mind people using my images "if" given a link back. However I'm in online gaming industry which attracts dodgy webmasters who scrap your source code and hotlink to images.

      These creeps give no recognition for the image, which can add up to gigs of bandwidth a month being stolen. It's unfortunate that honest webmasters these days have to protect their content, images and basically anything on their site from being scrapped.

      Just as piece of free seo advice, if your site uses an rss/atom feed…only post extracts to it, don't post full text content. It makes it less attractive to scrappers.

  • Salman

    Hi Patrick,

    I have a situation here which I think you can help me with. I want to use mode_rewrite for following puropose.

    I want to redirect any request coming from a browser asking for html to http://www.example.com/page/whaterWasThereAfterTheDomainName

    and if a request is coming for rdf/xml wheter from a browser or a someother interface I want to redirect it to http://www.example.com/resource/whaterWasThereAfterTheDomainName

    I can handle the content negotiation however when I get into loop with this rewrite rule

    # Rewrite rule to serve HTML content from the vocabulary URI if requested
    RewriteCond %{HTTP_ACCEPT} !application/rdf+xml.*(text/html|application/xhtml+xml)
    RewriteCond %{HTTP_ACCEPT} text/html [OR]
    RewriteCond %{HTTP_ACCEPT} application/xhtml+xml [OR]
    RewriteCond %{HTTP_USER_AGENT} ^Mozilla/.*
    RewriteRule ^(.*)$ http://www.example.com/page/$1 [R,L]

    It does add page in the URL but then it gets stuck in the loop and have somehing like this /page/page/page/page/person/….

    Thank you very much in anticipation.

    • http://www.blogstorm.co.uk Patrick Altoft

      Salman I’m afraid this is beyond me. Sorry

  • Daniel

    hi everyone, how can I create .htaccess URL Rewrite like my website

    (to) http://www.domain.com/username1/index.php

    and same like

    (to) http://www.domain.com/username1/index.php

    please help. tys for u reading.

  • Daniel

    Oh sorry I mean when I type


    that will go to


    and they will show http://www.domain.com/normal-username1/index.php on the web and hide the real link >> http://www.domain.com/user/normal/username1/index.php

    I dont want they know the real link. plz help

  • Salman

    Hi Daniel,

    I think if you use
    RewriteEngine on
    RewriteRule http://www.domain.com/normal-username1/index.php http://www.domain.com/user/normal/username1/index.php [P]

    this should serve your purpose. [P] is used for proxy, so it will still keep your first URL but will fetch information from second one.

  • surya

    i want to learn all about .htaccess from basic.
    How i can do
    I have site like


    How i can hide or make url like

    Please Help me for this

  • rod

    bloody nice tutorial thanx

  • aliasad

    Hi friends I want to make some dynamic content based on the $_GET variables passed to the index.php.
    For example
    But the problem is this that these sort of urls are no SEO Friendly.
    I want to use mod rewrite to get following results.
    If someone query like this
    should be changed to
    and second requirement
    should be changed to

    Can someone help please.

  • Pingback: user friendly URLs - DesignersTalk()

  • http://www.jerseyshoreseasonepisodes.com David

    Great post, thanks, this really helped me out with creating a .htaccess file!!!

  • Sarz
  • http://www.security-science.com arnel
  • http://dirlink.ro Dorin

    Hi, i would like to know how to rewhrite :

    http://example.com/file.html into http://example.com/file

    so the extension of the file will not be showing

    • itisrama

      RewriteRule ^([^/.]+)/?$ $1.html

  • http://mynichefinderreview.com Niche Finder Review

    Hello there, You’ve done a great job. I’ll certainly digg it and personally suggest to my friends. I am confident they’ll be benefited from this site.

  • Omar Borjas

    Thanks very useful info!!

  • Sean

    I need to make the following changes to my server’s httpd.conf

    Options FollowSymLinks
    AllowOverride All

    AllowOverride All
    AccessFileName .htaccess
    However, i was told that making direct change is not possible as it is a shell server so there is a need to use mod_rewrite via a .htaccess file.

    My question is now, how do I convert the codes? I’ve tried searching everywhere but could not find any answer to this. Sorry that I am a newbie in this area.

    Thank you very much.

    Regards, Sean

    • Sean

      The code is actually

      Options FollowSymLinks
      AllowOverride All

      AllowOverride All
      AccessFileName .htaccess”

      • Sean

        Options FollowSymLinks
        AllowOverride All

        AllowOverride All
        AccessFileName .htaccess

        • Sean

          Damn it. Sorry for the spam. I meant to type

          Options FollowSymLinks
          AllowOverride All

          AllowOverride All
          AccessFileName .htaccess

  • http://gamepie.ru/ Браузерные игры

    Thanks for any other informative web site. The place else may I am getting that kind of info written in such a perfect approach? I have a mission that I am just now running on, and I have been on the glance out for such information.

  • http://smartframeworkbd.com arif

    I have a cms site and i want to rewrite the dynamic url. For example current about page url of my site is http://smartframeworkbd.com/beautiful/index.php?option=content&cat_id=1&itemId=1
    I want to rewrite it as http://smartframeworkbd.com/beautiful/content/about
    Thanks in advance for solution

  • http://www.facebook.com/showtimelimos Showtime Limousines Perth

    I would appreciate any help to edit my htaccess (made to eliminate canonical errors), to change the redirections from http://www.example.com to http://www.example.com

    Options +FollowSymlinks

    RewriteEngine On

    RewriteCond %{THE_REQUEST} ^.*/index.html

    RewriteRule ^(.*)index.html$ http://www.example.com.au/$1

    RewriteCond %{HTTP_HOST} ^example.com.au$

    RewriteRule (.*) http://www.example.com.au/$1 [R=301,L]

  • http://deanlynn.com/ Dean Lynn

    Great tutorial! Really helpful.

  • hitesh ramnathkar

    Hello Patrick,

    I a trying to use mod rewrite to change url

    this is what i am putting in my .htaccess file

    RewriteEngine On
    RewriteRule ^astrologer-specialist.php$ /services.php?smid=1 [QSA,L]

    but the url rewriting is not taking place please help…

  • Qamar

    Nice Article

  • Jay Bush

    Fantastic post, this makes a great cheat sheet, and you’ve saved me a bunch of time

Like what you see? Talk to an Expert