Common Routing Patterns in .htaccess
Every web project eventually needs URL routing beyond simple page-to-page redirects. Whether you are enforcing a canonical domain, hiding file extensions for cleaner URLs, routing everything through a single entry point, or putting up a maintenance page during deployments, .htaccess provides battle-tested patterns for all of these scenarios.
This guide collects the most common routing patterns you will encounter in real-world projects. Each pattern is presented with a clear explanation, ready-to-use code, and notes on common mistakes. If you have already read through the fundamentals of redirects and URL rewrites, this is where you put that knowledge into practice.
WWW vs Non-WWW Canonicalization
Search engines treat www.example.com and example.com as two separate sites. If both versions serve the same content, you are creating duplicate content, which dilutes your SEO ranking and confuses crawlers. You must pick one version and redirect the other to it.
Redirecting WWW to Non-WWW
This is the most popular choice for modern websites. It produces shorter, cleaner URLs.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
</IfModule>
How it works:
RewriteCond %{HTTP_HOST} ^www\.(.+)$checks if the hostname starts withwww.and captures everything after it into%1.RewriteRule ^(.*)$matches any URL path and captures it into$1.- The substitution
https://%1/$1builds the new URL using the domain withoutwww.and the original path.
| Request | Redirects To |
|---|---|
http://www.example.com/about | https://example.com/about |
https://www.example.com/blog/post | https://example.com/blog/post |
https://example.com/about | No redirect (already correct) |
Redirecting Non-WWW to WWW
Some organizations and larger sites prefer the www version. The www subdomain also offers more flexibility with DNS (for example, you can point a CNAME record at a CDN).
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^localhost$ [NC]
RewriteCond %{SERVER_ADDR} !=127.0.0.1
RewriteCond %{SERVER_ADDR} !=::1
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
The additional conditions for localhost, 127.0.0.1, and ::1 prevent the rule from firing during local development. Without them, your local environment would try to redirect to www.localhost, which does not exist.
Always use 301 (permanent) redirects for canonicalization. A 302 redirect tells search engines the original URL might come back, so they will not transfer ranking signals to the canonical version. Using 301 ensures search engines consolidate all authority on your chosen URL.
Common Mistake: Protocol-Unaware Canonicalization
Wrong approach:
# This redirects to https:// even if you don't have SSL configured
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
If your site does not have an SSL certificate, hardcoding https:// will cause a connection error. If you need to support both HTTP and HTTPS dynamically, detect the protocol first:
Correct approach (protocol-aware):
<IfModule mod_rewrite.c>
RewriteEngine On
# Detect the current protocol
RewriteCond %{HTTPS} =on
RewriteRule ^ - [E=PROTO:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^ - [E=PROTO:http]
# Redirect www to non-www using the detected protocol
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ %{ENV:PROTO}://%1/$1 [R=301,L]
</IfModule>
The E=PROTO flag sets an environment variable that stores the current protocol, which is then used in the substitution. This way, HTTP requests stay on HTTP and HTTPS requests stay on HTTPS.
Domain Canonicalization
Sometimes you need to consolidate traffic from multiple domains onto a single primary domain. This is common after rebranding, acquiring competitor domains, or merging several sites into one.
Redirecting Multiple Domains to One
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect old domains to primary domain
RewriteCond %{HTTP_HOST} ^(www\.)?old-brand\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^(www\.)?another-domain\.net$ [NC,OR]
RewriteCond %{HTTP_HOST} ^(www\.)?typo-domain\.com$ [NC]
RewriteRule ^(.*)$ https://primary-domain.com/$1 [R=301,L]
</IfModule>
Each RewriteCond checks for one of the old domains. The [OR] flag means any one of them being true is enough for the rule to fire. The (www\.)? part makes each condition match both the www and non-www versions.
| Request | Redirects To |
|---|---|
http://old-brand.com/products | https://primary-domain.com/products |
https://www.another-domain.net/about | https://primary-domain.com/about |
https://primary-domain.com/about | No redirect (already correct) |
Redirecting a Specific Path on a Different Domain
In some cases, only certain paths from an old domain need to be redirected to specific pages on the new domain:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?old-brand\.com$ [NC]
RewriteRule ^support/?$ https://primary-domain.com/help-center [R=301,L]
RewriteCond %{HTTP_HOST} ^(www\.)?old-brand\.com$ [NC]
RewriteRule ^(.*)$ https://primary-domain.com/$1 [R=301,L]
</IfModule>
Place more specific rules before general ones. In the example above, the /support rule must come before the catch-all rule, otherwise it would never be reached.
Clean URLs (Removing File Extensions)
Clean URLs without .html or .php extensions look more professional, are easier to remember, and are generally better for SEO. Instead of example.com/about.html, users see example.com/about.