How to use Apache mod_rewrite

Posted on Saturday September 24, 2011 by Eric Potvin

Apache mod_rewrite make your website well organized and can significantly reduce your code. It is also known to be the SEO best friend or the guru of URL manipulation. In this article, you will learn the basics of mod_rewrite, how to use it and where to use it to maximize your Web Site usability.

When to use Apache mod_rewrite:

  • Improve users usability;
  • Redirect bad requests;
  • Redirect moved web pages to a new location;
  • Optimize your SEO search results;
  • Duplicate search engine results links;
  • and many more;

Make sure "mod_rewrite" is installed.

RewriteCond Operators / Patterns

  • < Is lexically lower;
  • > Is lexically greater;
  • = Is lexically equal;
  • ! Is not;
  • -d Is a Directory;
  • -f Is a regular file;
  • -s Is a regular file with a size greater than 0;
  • -l Is a symbolic link;
  • -F Is existing file via sub requests;
  • -U Is existing URL via sub requests;

RewriteCond Flags

  • nocase or NC Makes the test case-insensitive, A = a;
  • ornext or OR Used to merge rules;

RewriteRule Flags

  • chain or C Chained with next rule;
  • cookie or CO Set a cookie: CO=NAME:VAL:domain[:lifetime[:path]];
  • env or E Set environment variable: E=VARIABLE:VALUE;
  • forbidden or F Force URL to be forbidden with HTTP response 403;
  • gone or G Force URL to be gone with HTTP response 410;
  • last or L Last rule. Stop the rewriting process here and don't apply any more rewrite rules;
  • next or N Re-run the rewriting process starting again with the first rewriting rule (Be careful of infinite loop);
  • nosubreq or NS Not for internal sub-requests;
  • proxy or P Force proxy. mod_proxy must be enabled in order to use this flag;
  • passthrough or PT Pass through to next handler;
  • qsappend or QSA Query string append;
  • redirect or R Force redirect with [=code]: 301 (moved permanently) or 302 (moved temporary);
  • skip or S Skip next rule(s): S=num (where num = number greater than zero);
  • type or T Force MIME type: T=MIME-type;

Regular Expressions

  • . Any single character;
  • [chars] One of the chars from the set;
  • [^chars] Not any of the chars from the set;
  • (string1|string2) string1 or string2;

Quantifiers

  • ? 0 or 1;
  • * 0 to N (N is defined as a number greater than 1);
  • + At least 1 to N (N is defined as a number greater than 1);

Grouping

  • (text) Allow characters to be grouped and quantified;

Anchors

  • ^ Start of line;
  • $ End of line;

Escape Special Characters

  • \char Escape special characters for use in a string;

Examples:

All examples below will work if you enable the mod Rewrite engine:

RewriteEngine On

You can also set a base location if you need:

RewriteBase /
RewriteCond -f: if is a file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond [OR]
RewriteCond %{HTTP_HOST} ^www.domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.domain.net$
RewriteCond for a User Agent
RewriteCond %{HTTP_USER_AGENT} ^FireFox
Redirect a specific link to a specific file
RewriteRule ^about(/?)$ /page/about.php [NC,QSA,L]
Redirect a dynamic link to a specific file
RewriteRule ^([a-z0-9\-]+)(/?)$ index.php?page=$1 [NC,QSA,L]
Redirect a dynamic link (width sub folders) to a specific file
RewriteRule ^([a-z\-]+)/([a-z0-9\-]+)$ index.php?category=$1&subcategory=$2 [NC,QSA,L]
Execute a site search
RewriteRule ^search/([a-z0-9\-\+]+)(/?)$ index.php?q=$1 [NC,QSA,L]
Redirect an image to another folder
RewriteRule ^wallpaper/(.*)\.(jpg|png|jpeg|gif)$ /images/$1.$2 [L]
Disabled user to access directly to the files folder
RewriteRule ^files(/?)$ - [F]
Redirect a subfolder to a folder
RewriteCond %{HTTP_HOST} ^user\.domain\.com$
RewriteRule ^/(.*) http://www.domain.com/$1 [R=301,L]
Redirect to a file except specific files
RewriteCond %{SCRIPT_FILENAME} !\/(login|register)\.php [NC]
RewriteRule ^([a-z0-9\-]+)$ index.php?title=$1 [NC,QSA,L]
Redirect non www to a www domain
RewriteCond %{HTTP_HOST} !^www.domain.com [NC]
RewriteRule (.*) http://www.domain.com/$1 [R=301,L]
Check if a www domain is used
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^([a-z]+)(/?)$ index.php?usewww=1 [NC,QSA,L]

RewriteCond %{HTTP_HOST} ^domain\.com$
RewriteRule ^([a-z]+)(/?)$ index.php?usewww=0 [NC,QSA,L]
Redirect to a mobile site
RewriteCond %{HTTP_USER_AGENT} "mobile|windows ce|blackberry|smartphone|iphone|android" [NC]
RewriteCond %{HTTP_HOST} !^m.domain.com
RewriteRule ^(.*)$ http://m.domain.com/$1 [R]
Set variable
SetEnvIf Host ^www\. page=www
SetEnvIf Host ^m\. page=mobile
rewriterule ^.*$ index.php?subdomain=%{ENV:page} [QSA,L]
Block bad bots
SetEnvIfNoCase User-Agent "^Wget" bad_bot
SetEnvIfNoCase User-Agent "^EmailSiphon" bad_bot
SetEnvIfNoCase User-Agent "^EmailWolf" bad_bot
SetEnvIfNoCase User-Agent "^libwww-perl" bad_bot
Deny from env=bad_bot
Language redirect
RewriteCond %{HTTP_HOST} ^([a-z]{2})\.domain\.com$  [NC]
RewriteCond %1 !^www$ [NC]
RewriteRule ^(.*)$ php.php?lang=%1 [NC,QSA,L]
Ignoring CSS files
RewriteCond %{REQUEST_URI} !^.*\.css.*$ [NC]
Redirect specific type of files
RewriteRule ^([a-z0-9\-_\.]+)\.(pdf|doc|ppt|zip|gif|jpg|png|wma)$ /media/$1.$2 [NC,L]