WP-Mix

A fresh mix of code snippets and tutorials

Canonical www via .htaccess

Creating canonical URLs for your site is an important part of good SEO. In this quick post, we’ll look at several .htaccess techniques for removing and requiring the www prefix, and additionally we’ll see how to remove any index.php appendage from all URIs.

To use any of these code snippets, add them to your site’s root .htaccess file (or add via server config). Check out the notes for more information.

Tip: To force both canonical www prefix and SSL/HTTPS, check out our tutorial on How to Redirect HTTP to HTTPS (Method #3).

Remove www from all URLs

This slice of .htaccess removes the www prefix from all URLs:

# remove www
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
	RewriteRule (.*) https://example.com/$1 [R=301,L]
	
</IfModule>

Edit example.com to match your domain and test well.

Note: here is alternate syntax for the RewriteCond:

RewriteCond %{HTTP_HOST} !^example\.com$ [NC]

Either way works just fine.

Require www for all URLs

Alternately, this slice of .htaccess adds the www prefix to all URLs:

# require www
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
	RewriteRule (.*) https://www.example.com/$1 [R=301,L]
	
</IfModule>

Edit example.com to match your domain and test well.

Remove the index.php from all URLs

This .htaccess snippet strips the index.php from all URLs:

# remove index.php
<IfModule mod_rewrite.c>
	
	RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.php\ HTTP/
	RewriteRule ^(([^/]+/)*)index\.php$ https://example.com/$1 [R=301,L]
	
</IfModule>

Edit example.com to match your domain and test well.

Also FYI, here is the same technique using a simpler sytnax:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php [NC]
RewriteRule ^index\.php$ https://example.com/ [R=301,L]

This does the same thing as the previous technique, although it is not quite as robust. Homework assignment: compare and understand the differences, explain why the first method is better for general use.

Remove www and index.php

Here is an example of how to combine the previous techniques:

# remove www and index.php
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
	RewriteRule (.*) https://example.com/$1 [R=301,L]
	
	RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.php\ HTTP/
	RewriteRule ^(([^/]+/)*)index\.php$ https://example.com/$1 [R=301,L]
	
</IfModule>

To instead require the www, just swap out the first two lines with those from the “require-www” technique, above.

Bonus: Drop-in www canonicalization

Some of my readers have asked about a plug-&-play version of the www/canonical snippet. Here you go..

Drop-in remove www

Here are several techniques to remove the www prefix.

Drop-in remove www (Method 1):

# remove www
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTP_HOST} ^(.*)\.(.*)\.(.*)$ [NC]
	RewriteRule (.*) https://%2.%3/$1 [R=301,L]
	
</IfModule>

Drop-in remove www (Method 2):

# remove www
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
	RewriteRule (.*) https://%1/$1 [R=301,L]
	
</IfModule>

Drop-in remove www (Method 3):

# remove www
<IfModule mod_rewrite.c>
	  
	  RewriteCond %{HTTPS} !=on
	  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
	  RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
	  
</IfModule>

Drop-in require www

Here are several techniques to require the www prefix.

Drop-in require www (Method 1)

# require www
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTP_HOST} ^www\.(.*)\.(.*)$ [NC]
	RewriteRule (.*) https://%1.%2/$1 [R=301,L]
	
</IfModule>

Drop-in require www (Method 2):

# require www
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTP_HOST} !^www\. [NC]
	RewriteRule (.*) https://www.%{HTTP_HOST}/$1 [R=301,L]
	
</IfModule>

Drop-in require www (Method 3):

# require www
<IfModule mod_rewrite.c>
	
	RewriteCond %{HTTPS} !=on
	RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
	RewriteCond %{HTTP_HOST} (.+)$ [NC]
	RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
	
</IfModule>

The only thing you need to check for any of these techniques is the HTTP protocol, such that you change https to http if required.

Notes

If you get a 500 server error for any of the above techniques, try replacing [R=301,L] with [R,L], should do the trick.

Some of these techniques may not be compatible on sites where subdomains are being used. Slight modification may be required for best results.

Before using any of the drop-in techniques, make sure that your URL structure employs a single top-level domain (TLD), like .com. Do not use the drop-in techniques for plural TLDs, such as .co.uk. So if your site is rocking a plural TLD that’s fine, just use one of the manual methods provided in the first half of this tutorial.

Also remember to test well before going live :)

Related / Resources

Learn more

.htaccess made easy