At its core, mod_rewrite operates through a simple but powerful syntax:
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule pattern substitution [flags] </IfModule>
The real magic happens in the pattern matching using PCRE (Perl Compatible Regular Expressions). Here's a basic example that forces HTTPS:
RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Understanding these PCRE patterns is crucial:
^
- Start of string anchor$
- End of string anchor(.*)
- Captures any character (except newline)([a-z]+)
- Matches one or more lowercase letters\d{4}
- Matches exactly 4 digits
Here are practical examples you'll frequently encounter:
1. HTTP to HTTPS Redirect
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
2. Non-www to www
RewriteEngine On RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
3. Old URL to New URL
RewriteEngine On RewriteRule ^old-page\.html$ /new-page.html [R=301,L]
Enable logging in your Apache config:
RewriteLog "/var/log/apache2/rewrite.log" RewriteLogLevel 3
Use the NC
(no case) and OR
flags carefully:
RewriteRule ^product/([0-9]+)/?$ /prod.php?id=$1 [NC,L]
- Place frequently accessed rules first
- Use
[L]
flag to stop processing when matched - Avoid complex regex in high-traffic scenarios
- Consider using
Redirect
orRedirectMatch
for simple cases
Here's a complex rule that handles multiple conditions:
RewriteEngine On RewriteCond %{REQUEST_URI} !^/static/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]
This rule:
- Excludes /static/ directory
- Checks if requested file doesn't exist
- Checks if requested directory doesn't exist
- Routes everything else to index.php
Always use 301 (permanent) redirects for moved content:
Redirect 301 /old-path.html /new-path.html
For parameter changes while maintaining SEO value:
RewriteRule ^category/([^/]+)/([^/]+)/?$ /products.php?cat=$1&subcat=$2 [L]
Apache's mod_rewrite module provides a powerful way to manipulate URLs through rule-based rewriting. The basic syntax follows this structure:
RewriteEngine On
RewriteCond %{REQUEST_URI} pattern [flags]
RewriteRule pattern substitution [flags]
mod_rewrite uses Perl-compatible regular expressions (PCRE). Key patterns include:
^
- Start of string$
- End of string.
- Any single character*
- Zero or more of preceding element+
- One or more of preceding element?
- Makes preceding element optional
HTTP to HTTPS Redirection
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
URL Format Conversion
Convert ?id=123
to /id/123
:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^(.*)$ /id/%1? [R=301,L]
Enable logging for troubleshooting:
RewriteLog "/path/to/rewrite.log"
RewriteLogLevel 3
Keep these in mind:
- Use
[L]
flag to stop processing further rules - Place most frequently matched rules first
- Avoid complex regex patterns when possible
Watch out for:
- Infinite redirect loops
- Case sensitivity issues
- Missing
RewriteEngine On
directive - Incorrect flag usage (e.g., forgetting
[R]
for external redirects)
Consider these when mod_rewrite might be overkill:
- Use
Redirect
orRedirectMatch
for simple redirects - Implement URL routing at application level when possible
- Use
Alias
for simple path translations