Getting Started: Apache mod_rewrite Methods

By Blane Warrene
We teamed up with SiteGround
To bring you the latest from the web and tried-and-true hosting, recommended for designers and developers. SitePoint Readers Get Up To 65% OFF Now

Apache’s mod_rewrite module appears to be the one area of Apache administration that generates the most questions. I seem to be a perpetual beginner when it comes to url rewriting, and I continue to dream up impossible wishes on a regular basis.

I also bother my own peers for their best rewrite hacks to build up my arsenal. However, having seen numerous queries on this powerful module, I thought sharing some of my own favorite (and basic) rewriting usage would contribute to those seeking answers.

In addition, I am sure we have some hidden rewriting ninjas hanging around the SitePoint community that will add in some missing magic we all could leverage.

As a final aside – my knowledge of rewriting has come almost exclusively from reading and re-reading (and re-reading!) the Apache HTTP docs and some serious Googling on the topic over the years. Regular expressions can be both your friend and your enemy! ;>)

These are generally added into either your httpd.conf file or into an .htaccess file. For some excellent advice on htaccess if you are using that route – see this.

Re-directing a sub-domain to a domain:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)$
RewriteCond %{HTTP_HOST} !^$
RewriteRule (.*)$1 [P]

Or if you want to force — even if visitors use to get to your site:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^$ [NC]
RewriteRule ^(.*)$$1 [R,L]

Perhaps you have a directory you need to point visitors toward within the DocumentRoot that contains your entry pages (like a beta test site):

RewriteEngine On
RewriteCond %{HTTP_HOST} ^$
RewriteCond %{REQUEST_URI} !^/beta/
RewriteRule ^(.*)$ /beta/$1

Re-directing users (and search engines) permanently to a new domain from an old domain during a migration (and letting them get to the page they wanted instead of just the new site’s root index page).

RewriteEngine on
RewriteCond %{HTTP_HOST} ^$
RewriteRule ^(.*)$$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^$
RewriteRule ^(.*)$$1 [R=301,L]

And finally — I see many questions about search engine friendly url’s and dynamic pages. I have used this simple rewrite I learned from a friend – however – this is where some contribution would be great as I see these questions over and over in the forums. By all means add your best rewrite methods for working with dynamic pages. I do not use this last tactic too often and it is quite rudimentary.

Allows to rewrite to

RewriteEngine on
RewriteBase /articles
RewriteRule ^news([^.]+).php$ news.php?id=$1

We teamed up with SiteGround
To bring you the latest from the web and tried-and-true hosting, recommended for designers and developers. SitePoint Readers Get Up To 65% OFF Now
  • Nice, I’ll have to try a few of those out.

    I tried a while ago to get (with or without www.) to point to Reason being, I’ve got a bunch of addon domains on my hosting account and I wanted my home directory to be organized ;) Didn’t work out too well though. (With cPanel, your “main” domain name is usually your public_html directory, and all addon domains are subdirectories of that.)

    I think I’ll try again, modifying some of those examples.

  • Hi Blane:

    Excellent Article. Need some clarification before I impliment the code you have written for our website.

    What is 302 redirection and is it the one which you have posted here ? Sometime back I heard that penalized by google due to wrong redirection of to and I have seen that PR goes ‘0’ for atleast 1 month, though recently they recover back the lost PR.

    Is their any advantages of redirecting to ?

  • I actually do not do that anymore on my domains – however – it remains popular. And I did not cease to use it for any particular reason – just did not see the need for my own domains.

    A 302 is a Moved “Temporarily” browser status code.

  • Stewart Vardaman


    I think there is. I’ve noticed that having a mix of www and no-www links can fragment your inbound links. It seems to make a difference with things like Daypop:

  • pippo

    I think I spent about last year and half here at sitepoint trying to support mod_rewrite’s questions. :rolleyes:
    So if you will feel that mr google and other resources won’t satisfy your questions you can take a look at the posts at our Apache forum.

  • Thanks for the great article, mod_rewrite is always very confusing to me, never been able to write a new rule without asking :-(

  • Good examples Blane !

    Here is some RewriteEngine lines used to create sub-domain ‘on-the-fly’ (using wildcards on the DNS as well). To have to work, just create a directory called xxx in /var/www_vhosts

    Hope it helps.

    RewriteEngine On

    # a ServerName derived from a Host: header may be any case at all
    RewriteMap lowercase int:tolower

    ## deal with normal documents first:
    # allow Alias /icons/ to work - repeat for other aliases
    RewriteCond %{REQUEST_URI} !^/icons/

    # check the hostname is right so that the RewriteRule works
    RewriteCond ${lowercase:%{SERVER_NAME}} ^[a-z-]$

    # concatenate the virtual host name onto the start of the URI
    # the [C] means do the next rewrite on the result of this one
    RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]

    # now create the real file name
    RewriteRule ^([a-z-]+)*) /var/www_vhosts/$1/$2

  • pippo

    based on my experience I’d say that

    > RewriteEngine on
    > RewriteCond %{HTTP_HOST} ^(.*)$
    > RewriteCond %{HTTP_HOST} !^$
    > RewriteRule (.*)$1 [P]

    This won’t work under .htaccess

    If you access you will be proxied to and not

    ( why not use as suggested by ? )

    The reason is that under .htaccess, i.e. under a per-directory context so within a directory of httpd.conf too,
    the / will be “stripped” from the front.
    So using within .htaccess or a directory block within httpd.conf
    (supposing .htaccess is under document root dir)

    RewriteRule (.*) etc$1

    with /image.gif $1 will be image.gif
    with /path/to/image.gif $1 will be path/to/image.gif

    > RewriteEngine On
    > RewriteCond %{HTTP_HOST} !^$ [NC]
    > RewriteRule ^(.*)$$1 [R,L]
    it’s always good to escape dots as you did before so
    RewriteCond %{HTTP_HOST} !^$ [NC]
    would be more correct from a syntax point of view

    > RewriteRule ^news([^.]+).php$ news.php?id=$1
    same here, escaping the dot is more correct
    RewriteRule ^news([^.]+).php$ news.php?id=$1

  • You are correct. As I do not use htaccess for anything – I absolutely directed readers to review Apache’s own guidance on the use of htaccess prior to pushing off from the dock. These do however work with direct httpd.conf edits.

    I should have been more clear on that – thanks for pointing that out and clearing it up Pippo.

  • Here’s a rewrite directive for making “clean URLs” – it turns a URL like “” into “”

    RewriteRule ^site/([a-zA-Z0-9]+)[/]?([a-zA-Z0-9]+)?[/]?([a-zA-Z0-9]+)?[/]?([a-zA-Z0-9=&]+)? /?c=$1&s=$2&z=$3&$4 [QSA]

    Only “site” and the first value is required – the second two values are optional.

    Using the ‘magic’ QSA directive allows query string data appended to the end of a URL to be added seamlessly to the GET data – so you could go “” without having to parse the query string specially.

  • Richard

    One reason to standardize on either or is to match an SSL certificate. A certificate issued to one name will not work with the other. (That’s my crude understanding and may be subject to exceptions; please correct me as necessary.)

  • DCF

    Suppose I want to force everything to, even if the person visits Could I just tweak the above example like this…

    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^$ [NC]
    RewriteRule ^(.*)$$1 [R,L]

  • Blane, I tried your code

    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^(.*)$
    RewriteCond %{HTTP_HOST} !^$
    RewriteRule (.*)$1 [P]

    on my domain but it doesn’t work.
    I also tried to use a modified version

    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^(.*)$
    RewriteCond %{HTTP_HOST} !^$
    RewriteRule (.*)$1 [P]

    but it doesn’t work either. I have code above in the root of my domain but calling doesn’t work, you can try yourself. Ideally, as per the code, it should call the file but it doesn’t. Any tips?

  • Sorry, the code present in my .htaccess file is

    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^$
    RewriteCond %{HTTP_HOST} !^$
    RewriteRule (.*)$1 [P]

    but it doesn’t work.

  • pippo


    Was your DNS configured to accept subdomains other than “www” and “empty” ?
    I don’t think so, orr at least it doesn’t seem so, because doing an “host” it cannot be resolved.

    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^$ [NC]
    RewriteRule ^.*${REQUEST_URI} [P,L]

    should be enough.

    Remember that mod_proxy module needs to be loaded from your httpd.conf

  • Well pippo, to be honest, my host allows only 5 subdomains on my package & I create them through cPanel provided to me. So I thought that by doing this, I may be able to create extra sub-domains. ;) Too bad it didn’t work. :(

  • Anonymous

    what exactly is that slash in front of $1 for?
    RewriteRule ^(.*)$$1 [R,L]

    when i do that, gets

    i removed the slash in the rewrite rule and now it works without doubling the /


  • Shashank Pundir

    Can anyone please help me in creating subdomain as i am having and i want if any user(yy) have made registration then a subdomain will be created as for that

    Please help me in that
    Thanks in advance

  • Wow! Thanks so much!
    I didn’t know .htaccess file was this important!

    I was finally able to make redirect to

    This was a problem because… half of my goggle rank was counting toward each URL.

    Thank you!


  • pragya


    Can you please solve a problem related to url rewriting.
    i have a server withapache 2.0.52 running on Red Hat Enterprise Linux.

    I have written url rewrite script in .htaccess file but the script is not working.
    Here is the script –

    Options +FollowSymLinks
    RewriteEngine on
    RewriteOptions MaxRedirects=10

    RewriteRule ^(.*)_(.*)_([0-9]*)_([0-9]*).html accessories-brand.php?BrandId=$3&CatId=$4

    RewriteRule ^(.*)_([0-9]+).html accessories-brand.php?By=BRAND&BrandId=$2

    RewriteRule ^(.*)_(.*)_([0-9]+)_p.html products.php?ItemId=$3

    What should be done so that the server reads the script and it works.
    Should i have to do some server settings for it.
    Please reply me soon.

    Thanks n Regards,