Catch-all Apache Virtual Host to Force WWW Redirect on Canonical Hostnames

I find myself doing the same thing with nearly every Web site that I launch on my VPS (and client VPS/dedicated servers). I was to use http://www.domain.com as the primary host and have http://domain.com permanently redirect (301) while keeping the request URI intact.

Today, I decided to simplify this configuration by using a single Apache virtual host to handle all "www redirects." I thought I'd share this simple little tip.

When using name based hosting with Apache, this is very simple with mod_rewrite:


<VirtualHost *:80>
    ServerName jamiekrug.com
    ServerAlias thekrugs.com

    RewriteEngine On
    RewriteRule . http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,NE,L]
</VirtualHost>

Now, as I add other virtual hosts to the server, I need only add a ServerAlias line to the above virtual host and I'm good to go.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Dan G. Switzer, II's Gravatar Why not use a regex instead?

RewriteEngine on

RewriteCond %{HTTPS} (on)?
RewriteCond %{HTTP:Host} ^(?!www\.)(.+)$ [NC]
RewriteCond %{REQUEST_URI} (.+)
RewriteRule .? http(?%1s)://www.%2%3 [R=301,L]

This will work for any domain without you having to every modify the rule in the future.
# Posted By Dan G. Switzer, II | 8/6/09 4:51 PM
Jamie Krug's Gravatar @Dan,

Thanks for the comment. I'm not sure I completely understand your suggestion. I understand how your example would work, but it accomplishes the same thing with the addition of handling SSL as well. However, my virtual hosts are always on port 80 or 443 and would never need to handle both SSL and non-SSL.

Would you place your example in the main config file, as opposed to a single VirtualHost? If so, this would become a problem if you have any non-www hosts with a third level domain (e.g., admin.mysite.com).

Now that I think of it though, I could place this rule in the default (first) VirtualHost, which I just use to trap (forbidden response) any requests resolving to the Web server that don't match a host name. Was this your intention?

Thanks again!
# Posted By Jamie Krug | 8/6/09 9:01 PM
Dan G. Switzer, II's Gravatar @Jaime:

How you use it is up to you. :) I was just pointing out that you can write a generic rule to handle mapping non-www to www for all domains. You could modify the check so that it only adds the www to domain written as domain.com and ignore anything with an identifier like admin.domain.com. I had a rule written that does this, but I can't find it. However, I think it was essentially something like:

RewriteCond %{HTTPS} (on)?
RewriteCond %{HTTP:Host} ^(?!www\.)([^.]+\.[^.]+)$ [NC]
RewriteCond %{REQUEST_URI} (.+)
RewriteRule .? http(?%1s)://www.%2%3 [R=301,L]

This should look for something like XXXXX.YYYYY and only affect those URLs--which means it ignores IP addresses as well.

The handling of SSL/NON-SSL is just so you can use it as a default handler for all sites. The check essentially keeps the protocol the user specified. If they request https://domain.com it'll redirect to https://www.domain.com, if they requested http://domain.com/ it'll redirect to http://www.domain.com/.

Anyway, just a suggestion. Lots of good reading on Google if you search for "apache rewrite non-www".
# Posted By Dan G. Switzer, II | 8/7/09 10:05 AM
BlogCFC was created by Raymond Camden.