6

To redirect non-www to www we often see this in .htaccess:

RewriteEngine on
RewriteCond %{HTTP_HOST}   !^www\.example\.com [NC]
RewriteRule ^(.*)          http://www.example.com/%{REQUEST_URI} [R=301,NE,L]

The problem is when we also have subdomains: http://wiki.example.com will be redirected to http://www.wiki.example.com A workaround is to add each subdomains to the regular expression. Not very nice.

So I redirect from non-www to www with this:

RewriteEngine on
RewriteCond %{HTTP_HOST}   ^example\.com [NC]
RewriteRule ^(.*)          http://www.example.com/%{REQUEST_URI} [R=301,L]

The condition is negated, and we can then safely use subdomains.

My question: how to have a "generic" .htaccess? i.e without giving the domain name? (less admin work, allow to have several domains pointing to the same directory, etc). I found something promising:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(?!www\.)(.+) [NC]
RewriteRule ^(.*) http://www.%1/$1 [R=301,NE,L]

But once again http://wiki.example.com will be redirected to http://www.wiki.example.com.

I don't figure how to add the www only when no subdomain is specified.

 

UPDATE
Thanks to people who gave answers, I finally used that:

RewriteEngine on
RewriteCond   %{HTTP_HOST}   !\..+\.
RewriteRule   ^   http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
0

2 Answers 2

4

I don't think you can make it completely generic, since you'll need to make exceptions for your subdomains, unless there is a pattern to your subdomains?

A workaround is to add each subdomains to the regular expression.

Well, yes unfortunately...

RewriteEngine on
RewriteCond %{HTTP_HOST} !^(wiki|sub2|sub3)\.
RewriteCond %{HTTP_HOST} ^(?!www\.)(.+)
RewriteRule (.*) http://www.%1/$1 [R=301,L]

I've removed the NC flag on the RewriteCond directive and the NE flag on the RewriteRule directive - these don't seem to be necessary here? Also the ^ (start of string) anchor is unnecessary when used with .*.

Alternatively, if your subdomains point to subdirectories off the main domain's document root then you could simply create a .htaccess for the subdomain (in the subdirectory) and enable the rewrite engine. mod_rewrite is not inherited by default, so this would override the main domains mod_rewrite directives and the canonical rewrite. So you would not need an exception for the subdomain.

In fact, you could then revert to your original canonical redirect! But make it generic...

RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]

UPDATE:

matching only when no www and only one dot ?

That's an idea. Although whether there should only be one dot or two dots will depend on the TLD, so it's still not totally generic. When there is only one dot there must be two parts with no dot (with a dot in between), so you can check for this with a pattern, such as:

RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]

You don't need to explicitly check for no www, since if there is only one dot then there can't possibly be a www subdomain, or any subdomain for that matter. This will match a domain such as example.com. For a double barrelled TLD, such as .co.uk, then you'll need to extend the pattern. You could handle .com and (most) UK domains with one pattern:

^[^.]+\.[^.]+(\.uk)?$

This will match example.com and example.co.uk, but not www.example.com or www.example.co.uk (or any subdomain).

However, this isn't perfect since you can register single barrelled UK domains these days. eg. example.uk. And the above regex will match www.example.uk - which is not desirable.

3
  • 1
    Can't we make a RewriteCond matching only when no www and only one dot ? I already tryed to make one, but I'm not fluent enought into RewriteCond. Commented Aug 29, 2015 at 12:59
  • 1
    That's an idea. I've updated my answer.
    – MrWhite
    Commented Aug 29, 2015 at 15:15
  • 2
    Thanks for the detailed explanations. I prefer Bertrand SCHITS's regexp. Commented Aug 30, 2015 at 0:54
2

I personnaly use this:

RewriteEngine on
RewriteCond %{HTTP_HOST} !\..+\.
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]

It checks if there is NOT 2 dots in the domain name. This is very similar to what w3d proposed, I just find it more readable. And as w3d stated, it is impossible to have a fully generic solution because nothing allow to guess how many dots your "bare" has. But still nicer to have a semi-generic solution.

Beware of the fact local access could be broken (http://localhost). In some cases you should add something like that:

RewriteCond %{HTTP_HOST} !=localhost

Or whatever suitable to match your special needs. So in summary, it is impossible to have a truly generic method.

1
  • 1
    Thank you for the clarifications (I guessed myself, but nice to be written for futur reference), and for the localhost warning. Commented Aug 30, 2015 at 0:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.