10+ Mod_Rewrite Rules You Should Know

August 18th, 2009

Mod_rewrite is an Apache-based rewrite engine for dynamically rewriting URLs. It’s built into Apache servers natively, though not enabled by default.

It’s capable of functions beyond simple rewrites, though, some of which are included below.

Mod_Rewrite Rules You Should Know

Turn Mod_Rewrite On

Mod_rewrite is used through your .htaccess file. Place the following code at the beginning of your .htaccess file to turn mod_rewrite on:

RewriteEngine on

(Don’t forget that .htaccess commands are case-sensitive.) This code needs to be entered at the beginning of any .htaccess file using mod_rewrite.

The Basic Mod_Rewrite Layout

The basic format for a mod_rewrite command is:

RewriteRule Pattern Substitution [Flag(s)]

URLs are Always Relative

The URL you redirect to is always relative to the directory in which your .htaccess file is placed. So if it’s in the root directory, URLs are all in relation to the root directory; if it’s in a sudirectory, URLs are in relation to that particular subdirectory.

A Basic Redirect

If you just want to create a simple 301 redirect from one URL to another, then use the following code:

RewriteRule ^fileone.html$ filetwo.html

This is a very basic rule that means any requests for fileone.html will be sent to filetwo.html.

Require no “www”

This bit of code will make it so visitors to your site don’t need to type in the “www” bit of your website address.

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

Block a Specific IP Address

If you want to block someone coming from a specific IP address from accessing your website, you can use the following code:

RewriteCond %{REMOTE_ADDR} ^(A\.B\.C\.D)$
RewriteRule ^/* [L]

Replace the A\.B\.C\.D with the IP address you want to block (don’t forget to leave the “\” before each dot, which escapes the character).

Block Specific User Agents

If you want to block a group of IP addresses using the same User Agent (bot), the following code with do it:

RewriteCond %{HTTP_USER_AGENT} UserAgent
RewriteRule .* - [F,L]

Just replace the “UserAgent” bit with whatever user agent you want to block. You can also block more than one at a time by replacing the top line in that code with something like this:

RewriteCond %{HTTP_USER_AGENT} UserAgentA [OR]
RewriteCond %{HTTP_USER_AGENT} UserAgentB

You can put as many user agents in as you want, just make sure you end each line with [OR] (with the exception of the last line, of course).

Strip Query Strings

Let’s say all the pages on your site other than your home page are formatted as follows, with query strings instead of page names:

Those aren’t very pretty, and on top of that, search engines will show a bunch of duplicated “home” pages. If you want to get rid of the query string in your page URLs, use the following code:

RewriteCond %{QUERY_STRING} example=
RewriteRule (.*)$1? [R=301]

This not only gets rid of the query string, but also the preceding question mark.

Set up a Default Image

Using a default, backup image in case of broken images can make your site look more professional. Use the following code to redirect to a default image for any image whose file cannot be found.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^images/.*\.jpg$ /images/default.jpg [L]

Of course, you can change the “.jpg” bit to whatever file type you’re using. Make sure you have an image called “default.jpg” or change that to whatever your default image filename is.

Prevent Hotlinking

The last thing most website owners want is other sites stealing their content or worse—hotlinking to their images and stealing their bandwidth. Here’s a simple bit of code that prevents it:

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)? .*$ [NC]
RewriteRule \.(gif|jpg|swf|flv|png)$ /feed/ [R=302,L]

Make sure you change the “” bit to your own domain name.

Redirect to a Maintenance Page

If you need to take your entire site offline for a bit and redirect to a maintenance page (or some other page), use the following code:

RedirectMatch 302 ^/ /maintenancepage.html

Change the “maintenancepage.html” bit to wherever your maintenance page file is located.

Redirect Multiple Domains to a Single Domain

If you have multiple domains pointing to your site, it’s possible you could take a hit in the search engines for having duplicate content. Use the following code to redirect visitors from two domains to just one:

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

Remember the Filesystem Always Takes Precedence

The filesystem on your server will always take precedence over the rewritten URL. For example, if you have a directory named “services” and within that directory is a file called “design.html”, you can’t have the URL redirect to “”. What happens is that Apache goes into the “services” directory and doesn’t see the rewrite instructions.

To fix this, simply rename your directory (adding an underscore to the beginning or end is a simple way to do that).


  • Because mod_rewrite works within the .htaccess file, commands are case sensitive.
  • Always back up your .htaccess file before making any changes to it. This way, if there’s a problem, you can easily restore your site.

More Resources:

Author: Cameron Chapman

Cameron Chapman is a writer, blogger, copyeditor, and social media addict. She’s been designing for more than six years and writing her whole life. If you’d like to connect with her, you can follow her on Twitter or at her Personal Website.

Write for Us! We are looking for exciting and creative articles, if you want to contribute, just send us an email.

The jungle is alive: Be it a collaboration between two or more authors or an article by an author not contributing regularly. In these cases you find the Noupe Editorial Team as the ones who made it. Guest authors get their own little bio boxes below the article, so watch out for these.


61 comments for „10+ Mod_Rewrite Rules You Should Know
  1. Julien on August 18th, 2009 at 3:52 pm

    Thanks. Those are always helpful.

  2. yasser on August 18th, 2009 at 3:54 pm

    Thanks alot for this article ..

    we hope to see more from noupe & cameron ..

  3. Jim Gaudet on August 18th, 2009 at 6:15 pm

    Damn, how to not sound spammy.

    Great list!

    That didn’t work. Anyway, this was one worth saving and sharing..


    • Cory on August 18th, 2009 at 7:53 pm

      Well, i guess my comment sounds spammy too :)

  4. Cory on August 18th, 2009 at 7:51 pm

    Just on time, thanks a lot for this great post :)

  5. Paul Decowski on August 18th, 2009 at 8:17 pm

    RedirectMatch is a mod_alias directive, not mod_rewrite (in Redirect to a Maintenance Page).

  6. Daniel on August 18th, 2009 at 9:14 pm

    I find it extremely ironic that you mention a rewrite for setting up default images (Quote: Using a default, backup image in case of broken images can make your site look more professional.) and yet down at the bottom of the page, under every comment, is a broken image…

  7. Joltivan on August 18th, 2009 at 9:28 pm

    thanks, I looking for this :)

  8. Doug Bell on August 19th, 2009 at 12:40 am

    Great list, but you should be careful: Some of these things are better off not using mod_rewrite.

    Redirect, Alias, and are also useful tools that are usually enabled by default.

  9. Ahmed on August 19th, 2009 at 1:01 am

    the problem im facing in wordpress how ican add www in the url

    • prafuitu on August 19th, 2009 at 2:07 am

      This is what you are looking for:

      RewriteCond %{HTTP_HOST} ^domain-name\.tld$ [NC]
      RewriteRule ^(.*)$ http://www.domain-name.tld/$1 [R=301,L]

  10. tintedPixel on August 19th, 2009 at 1:20 am

    How about a mod_rewrite Fix for Controlling updated files and Caches:

    RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /z/([a-z]+)/(.+)-([0-9]+)\.(js|css).*\ HTTP/ [NC]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .+ /z/%2/%3.%5 [NC,L]


    Cache-Friendly File Names that allow you to update javascript and css files in my visitors cache’s simply by naming them differently in the html, on the server they stay the same name.

    RewriteRule ^directory/(j|c)/([a-z]+)-([0-9]+)\.(js|css)$ /directory/$1/$2.$4 [L]

  11. richard on August 19th, 2009 at 1:38 am

    thank you so much for this post! I have been meaning to consolidate my .com and .me domains, and strip the www. prefix — you’ve helped me do exactly that, and also disable hotlinking and add in maintenance page references for future use. Thanks again!!

  12. John Moray on August 19th, 2009 at 1:50 am

    Remember to never put rewrite rules in .htaccess because they will be interpreted and compiled at each request, which is something neither you and your hosting service want.

  13. prafuitu on August 19th, 2009 at 2:00 am

    * URLs are Always Relative – FALSE. URLs are relative to the current directory only if no RewriteBase directive is used, in which case the URLs become relative to the specified path. ( Also, you can use absolute URLs by specifyng the protocol to be used.

    * …so visitors to your site don’t need to type in the “www” bit… – WRONG. That has nothing to do with making the “www” optional. It’s related to SEO, creating a single entry-point to your website by redirecting all your visitors (including search engines) to your “domain-name.tld”. This way, the search engines won’t index the same page twice, making it lose its strength.
    This rule should be accompanied by a rule to remove file names such as “index.php”, “index.php5”, “index.asp”, “index.htm”, “index.html”, “default.html”, etc, which all point to the same page, the homepage. If a user can see the homepage on multiple different URLs, so can a search engine, which will index it as X different pages (X being the number of available URLs for the homepage)
    You should be using something like this:
    RewriteRule (index|home|default)\.([a-zA-Z0-9]{3,4})$ / [R=301,L]

    Also, 302 is “Found” while 301 is “Permanently Moved”. They are both redirects but the second should be used for permanent rules. The second tells the crawler to “forget” this URLs as the resource associated with it has been moved to the new location and that is the URL that it should be using from now on. The first one just says: “Ok, for now, what you are looking for has been moved someplace else, but you should check this URL again in the future as the resource might become available again”

    Also, I don’t agree with the statement that “a default image would make your site look more professional in case of a broken image URL”… You could say, at best, that it would make your site look less dilettantish, as a professional wouldn’t have broken links on any of his pages. :P

    * Remember the Filesystem Always Takes Precedence – are you absolutely sure about that? ‘Cause I’m pretty sure that if I have this rule:

    RewriteRule ^dir-name(.*)$ file-name.php [NC,L]

    and I try to access http://my-domain.tld/dir-name/other-file.html, even though there is an other-file.html in a dir-name, I will get the contents of file-name.php
    I’m sure about that because I use this in all of my projects and I always have to specify which folders I want to exclude from my rules. E.g: I redirect absolutely everything to the index.php file (which acts as a bootstrap file) and I use something like:

    RewriteRule ^assets(.*)$ – [NC,L]

    to allow users to access the contents of the “assets” folder, where I usually keep the image/css/javascript files…

    These being said, I’ll give you the “thumbs up” for the initiative and, sadly, a “thumbs down” for the quality of the content… :(

    • prafuitu on August 19th, 2009 at 2:29 am

      I forgot this…

      Let aside the fact that RedirectMatch is a mod_alias directive, not a mod_rewrite, there is no way your example would ever work, because any “maintenance” file name you would use, it would be matched by the given regex, resulting in a neverending redirect…

      What you could use instead is:

      RewriteCond %{REQUEST_URI} !maintenance.html$ [NC]
      RewriteRule .* /maintenance.html [R=302,NC,L]

      However, this would also block users to access the images or css files, so you will have to add more RewriteConds to that set, making it look something like:

      RewriteCond %{REQUEST_URI} !^/css [NC]
      RewriteCond %{REQUEST_URI} !^/images [NC]
      RewriteCond %{REQUEST_URI} !^/js [NC]
      RewriteCond %{REQUEST_URI} !^/maintenance.html$ [NC]
      RewriteRule .* /maintenance.html [R=302,NC,L]

      • Bruce L on February 1st, 2011 at 6:58 pm

        Thank you so much for this – exactly what I was looking for.

        I’ve been searching for hours looking for how to allow the images to show on my outage page, realizing they were caught in a redirect loop.

    • iFlash on June 3rd, 2011 at 2:08 pm

      Can I get a contact Mr. Prafuitu?

  14. derschreckliche on August 19th, 2009 at 2:33 am

    So this one will Block IE6, right?

    RewriteCond %{HTTP_USER_AGENT} ‘MSIE6’
    RewriteRule .* – [F,L]

    • superdit on August 23rd, 2009 at 9:01 am

      oupp yes now i know to block IE6 thanks

  15. Nick on August 19th, 2009 at 6:04 am

    Thanks for the article. I’m a mod-rewrite newbie struggling with an issue…

    I have a current directory path:

    I want to redirect all attempts to blah/ to and want to retain the special code included in the initial URL.

    I’ve essentially re-written a complete section of the site in a mini-MVC model and need to convert traffic going to the old pages to the new model. I can do this in PHP, but want to completely get rid of blah/ and never look at it again.

    Any help would be appreciated.


  16. Nick on August 19th, 2009 at 6:05 am

    Thanks for the article. Im a mod-rewrite newbie struggling with an issue…

    I have a current directory path:

    I want to redirect all attempts to blah/ to and want to retain the special code included in the initial URL.

    I’ve essentially re-written a complete section of the site in a mini-MVC model and need to convert traffic going to the old pages to the new model. I can do this in PHP, but want to completely get rid of blah/ and never look at it again.

    Any help would be appreciated.

  17. Kaplang on August 20th, 2009 at 4:40 am

    thanks for the post, really useful stuff :)

  18. hossein on August 21st, 2009 at 4:56 pm

    it was a good tutorial

    i have an old problem with htaccess and i wonder if you could help me whith it. please please please please help

    i want to do this with my htaccess
    the role :

    1 – users request a url like :
    2- apache should know show

    BUT idont want the user to see the second url in his/her addressbar can you help me?

    if you had any thing to say please mail me and let me know . thanks again

  19. Lit_Tiger on August 28th, 2009 at 11:48 pm

    Thanks , Useful post

  20. Asad on December 16th, 2009 at 5:25 am


    suppose, there is a url
    I want to redirect it to

    Can any one help me, how is this possible,



  21. Dominica on January 29th, 2010 at 1:29 am

    Hi people

    How do i hide every fileextensions like .php or .asp or .html etc
    i want like this

    from to


  22. Anup on March 13th, 2010 at 3:56 am

    Thanks for these cool tips.

  23. Jos on April 14th, 2010 at 8:07 am

    Excelente articulo, gracias. Muy buenos algunos para aplicar.

  24. Mohit on April 27th, 2010 at 8:57 am

    Thanks a lot! very useful infomation.

  25. Rich Bowen on May 24th, 2010 at 3:34 am

    Please don’t link to the 1.3 version of the mod_rewrite docs. Please instead link to

    We’ve been working very hard to make them more accurate and more useful, and it’s very frustrating to find articles like this linking to the 1.3 docs which are significantly out of date.

  26. Alberto Douglas on August 11th, 2010 at 5:36 am

    Thanks a lot! very useful infomation,was looking for a tutorial as simple as this.

  27. Inception 2010 on September 11th, 2010 at 3:48 pm

    Hats off for the ingenius post. kudos!

  28. Brett Widmann on October 24th, 2010 at 12:17 am

    Great set of tips and nice code! Thanks for sharing

  29. Ajay on November 26th, 2010 at 10:36 am

    Thanks , thank u very much. its very easy to understand

  30. Irvin Pumper on November 27th, 2010 at 2:31 pm

    Evening i just came across your site from Google but got a strange popup about cat hospitals which is obviously not related to your site. Is this your ads or do i have a spyware issue? Thanks.

  31. shohan on December 7th, 2010 at 3:54 pm

    just,i was searching for this type of article..
    mod rewrite is cool !! thanks writer !

  32. Sourav on December 10th, 2010 at 5:58 am

    If i have a page like this “” and I want to show the url as “” what should I write? Can anyone email me?

    There are several pages in this domain which I want same kind of redirection. Whats the method?

  33. share your talent on February 1st, 2011 at 7:44 am

    I’ve truly appreciated reading your articles. You obviously know what you are talking about! Your internet site is so effortless to navigate as well, I’ve bookmarked it in my favourites :-D

  34. Brian Norman on February 21st, 2011 at 11:52 pm

    How do i redirect a request for http://my_server/cgi-bin/xxx
    back to the requesters ip eg http://hackers_ip/cgi-bin/xxx

  35. Mark on April 5th, 2011 at 4:59 pm

    Thank you for this article, it really helped to stop an iPhone developer from harvesting the latest lottery numbers from our website at each time a user accessed their app – up until now it has been eating almost 2Gb a month in bandwidth.
    Keep up the good work, love the site!

  36. Kaushik Biswas on April 20th, 2011 at 10:30 pm

    I need a little help. Every day I find some visitors using Googlebot as their browser’s User Agent while visiting my site. I want to stop the fake Googlebots. How can I allow the real ones and keep out the fake ones? Is there any way to do this via htaccess?

  37. Jatin on April 30th, 2011 at 8:09 am

    Few of the rules mentioned here are really cool. Thanks.

  38. Anoir Hama on May 19th, 2011 at 1:11 am

    Helpful tutorial, thx for the explanation, by the way I’m stuck on redirecting Html/php sample pages with no DB to .Aspx/.pl/.do or any other extension :S

    Example: or index.html
    to: or any other perfect extension
    Please help me to rewrite rules on the file .htaccess

    (!) You can also keep in touch with me or email me at:

  39. sajin on August 10th, 2011 at 6:15 pm


    I wan a small help if you can

    My site url is

    In this view is a Page
    and vendor is a function inside the same page

    i wan to rewrite the url to

    sajin will change dynamicall as its users name

  40. muhammed sekertekin on October 20th, 2011 at 12:32 pm

    wow very nice article it helps me a lot iam now removing all the query string in my website i was told it will help me rank in search engines muhammed sekertekin

  41. Robert on November 19th, 2011 at 4:17 pm

    I am trying to redirect
    but it does not work, what am i doing wrong?
    RewriteRule kategorier\?uid=([0-9]+) index.php?option=com_comprofiler&task=userProfile&user=$1 [R=301,L]

    Regards Robert

  42. tyler on December 11th, 2011 at 7:53 pm

    Unfortunately this did not help me with my issues. Thanks though

  43. ahmadMarafa on January 17th, 2012 at 9:53 pm

    thanks for your post , that’s really help
    but how to avoid css,js and images dirs reWriten ?

    thanks for help

  44. Anon on April 16th, 2012 at 7:03 pm

    Great resource! After weeks/months of trying to get some basic mod rewrite sources, this site gave me all the answers I needed. Thanks!

  45. mrbi11 on June 4th, 2012 at 4:26 am

    First and foremost, thanks for this. Helpful.

    fyi More Resources: couple out of date links in there

  46. Hari on July 25th, 2012 at 8:53 pm

    i want to redirect 20 php urls to single url. iam using below command, Can any one confirm is it work or not?

    RewriteRule ^/(korean/|portugues/|francais/|japanese/|deutsch/|italiano/|espanol/|chinese/|russian/)?main/piv\?.php /page.php?page_id=$1 [L,R=301]

  47. Jamal on August 4th, 2012 at 5:17 pm

    Is there a way to deny an entire tdl? For example if I want to deny anything coming from .ru (russia) domains , can this be don using deny rules or is this only possible with the actual IPs.

  48. kunu on September 2nd, 2012 at 5:03 pm

    Hi Cameron Chapman,

    My website is running under https and all pages are using https. But one iphone api url is need to use http.
    I need to change url to use http rather than https.

    Also if anyone will use url, it should not redirect to https.

    My current .htaccess in DocumentRoot as follows.

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule .* ./index.php

    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

    RewriteCond %{SERVER_PORT} ^80$
    RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

    Please help me. It is urgent.


  49. robsku on September 14th, 2012 at 1:50 am

    Regarding hotlink-blocking, I wrote a PHP script to circumvent just this after writing a very nice review of a webpage on my stumbleupon page with IMG tag pointing to cool image on the page that I felt was likely to attract visitors to check that page considerably better than just my writing and ending up with my article blaming me, in very insulting and rude words, for being bandwidth stealing low-life scum using hotlinking for my benefit on his expense.

    It made me feel bad, for I was merely using his bandwidth to attract visitors to his site, and while causing perhaps some extra traffic from those who saw my review but didn’t visit his page it provided more visitors to his site for compensation – I don’t think it’s a bad deal and he certainly didn’t have to insult me that badly…

    I made a PHP script that, using my bandwidth to promote his and other hotlink blockers sites… Unfortunately also any such site I would use it would get two requests for same image when someone visits the page through mine as normally the visitor would get it from browser cache when loading the page – but really the only one who might notice any impact because of increased bandwidth use could be the visitor, and even then only if using really bad connection, like GSM/GPRS :)

    Good thing is, I now have PHP script to not only counter hotlink block for images but also, since I didn’t feel that writing script just for that was worth of my time, I made it’s no. 1 purpose be image thumbnail script, with query parameters for max- width & height, URI (relative & absolute local server URI’s, as well as remote URL’s and if configured even file paths on server – with settings for base directory and regexp’s to filters to accept and/or deny matching paths), optionally converting to PNG or JPEG with optional settings for PNG only if originally JPEG to avoid further quality loss, only if resized (as PNG is likely to be larger w/ no benefits), to convert GIF’s to 8-bit PNG’s for smaller size, also possibly only if resized, to convert from whatever to 1-bit B/W, 2-8-bit greyscale or color and with or without using 1-bit for trasparency and so on similarly for JPEG to trade size for quality, even to GIF (for whatever reason – maybe to support transparency on ancient IE’s ;) ) – but ended up putting only couple of these to actually available on query + option for smart guess auto-decision converting to PNG32 for resized JPEG’s, PNG8 for resized GIF’s, and ignoring all other conversion options, but option to convert to JPEG from PNG or even if resized from already JPEG to place small size the highest priority in all cases. Sadly I never achieved but small part of these options coded… >:D

    Two options originally planned came after all this craziness, one for remote URL (really not separate option, just added setting referer to domain address of the URL) and lastly setting custom referer separately.

    What I have wondered, just out of curiosity – is there any way, other than blacklisting known IP’s using scripts like this, to identify and block this kind of tools without also blocking legitimate visitors with browser set to not send referer or using anonymous proxy network, such as Tor?

  50. riyon on September 22nd, 2012 at 9:47 pm

    Great tut.Always helpful to visit this iste

  51. samsamX on November 9th, 2012 at 11:27 am

    Another nice snippet, to add “.html” at the end of all you url (and remove “/” if there’s one) :
    RewriteCond %{REQUEST_FILENAME} -d [OR]
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .* – [S=2]
    RewriteRule ^(.*)/$ $1.html [L,R=301]
    RewriteRule !\.html$ %{REQUEST_URI}.html [L,R=301]

  52. Aaron on December 3rd, 2012 at 1:59 pm

    Thanks a lot, this surely helped me :D

  53. Jerry on February 17th, 2014 at 8:22 am

    I always mess up the htaccess file. Thanks for these tips should definitely make me a better coder.

  54. Rob on July 8th, 2010 at 8:28 am

    NICE Tute… I haven’t ever seen such a thorough, and simple tute on this subject..

    Much Love,