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
RedirectorRedirectMatchfor 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 Ondirective - Incorrect flag usage (e.g., forgetting
[R]for external redirects)
Consider these when mod_rewrite might be overkill:
- Use
RedirectorRedirectMatchfor simple redirects - Implement URL routing at application level when possible
- Use
Aliasfor simple path translations