When migrating domains in Apache, many developers encounter a common pitfall with RewriteCond
directives. The default behavior chains conditions with AND logic, but we often need OR conditions for domain redirection scenarios.
# This doesn't work as expected (AND logic)
RewriteCond %{HTTP_HOST} ^olddomain.com [NC]
RewriteCond %{HTTP_HOST} ^www.olddomain.com [NC]
RewriteCond %{HTTP_HOST} ^newdomain.com [NC]
RewriteRule ^/(.*)$ http://www.newdomain.com/$1 [R=301,NC]
The simplest approach is to use the [OR]
flag on conditions:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.olddomain\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^newdomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
For cleaner configuration with fewer conditions:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?(olddomain|newdomain)\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
- Always use
R=301
for permanent SEO-friendly redirects - The
L
flag stops further rule processing - Escape dots in domain names (
\.
) - Consider adding
QSA
flag if you need to preserve query strings
ServerAdmin webmaster@localhost
ServerName newdomain.com
ServerAlias www.newdomain.com olddomain.com www.olddomain.com
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.newdomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
DocumentRoot /var/www/newdomain.com/www/
# Other configurations...
Use curl -I
to verify redirects:
curl -I http://olddomain.com
curl -I http://www.olddomain.com/some-page
curl -I http://newdomain.com/about
When migrating from olddomain.com to newdomain.com, proper URL handling becomes crucial for SEO preservation. The key requirement is to redirect all variations (with/without www, old/new domains) to a single canonical URL (www.newdomain.com).
The original approach attempts to handle multiple domains using consecutive RewriteCond directives:
RewriteCond %{HTTP_HOST} ^olddomain.com [NC]
RewriteCond %{HTTP_HOST} ^www.olddomain.com [NC]
RewriteCond %{HTTP_HOST} ^newdomain.com [NC]
RewriteRule ^/(.*)$ http://www.newdomain.com/$1 [R=301,NC]
This creates an AND relationship between conditions - meaning ALL conditions must match simultaneously (which is impossible). What we actually need is an OR relationship.
Option 1: Using the [OR] Flag
The simplest solution is adding the OR flag between conditions:
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.olddomain\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^newdomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
Option 2: Regular Expression Pattern Matching
Combine patterns into a single condition using regex alternation:
RewriteCond %{HTTP_HOST} ^(www\.)?(old|new)domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
Option 3: Separate Rules for Each Case
Some prefer explicit rules for better readability:
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.olddomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^newdomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
- Always use 301 (permanent) redirects for SEO
- Test with curl -I before going live
- The [L] flag terminates further processing
- Escape dots in domain names (\. instead of .)
- Consider adding these rules to .htaccess if you don't have server access
Here's the full corrected configuration:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName newdomain.com
ServerAlias www.newdomain.com olddomain.com www.olddomain.com
DocumentRoot /var/www/newdomain.com/www/
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.newdomain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(old|new)domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
# Other configuration...
</VirtualHost>