Common htaccess snippets for your SEO needs

To save myself from looking into various Github projects I decided to make a collection of my most commonly used .htaccess snippets. Most of these snippets I use when optimizing websites for SEO to make sure all rewrites and redirects are in order.

Rewrites & Redirections

Redirect 301 single page

Redirect 301 /oldurl

Force SSL (HTTPS) on every page

HTTP 301 redirects all traffic to the HTTPS version of website ( ->

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$$1 [L,R=301]

Force no WWW

HTTP 301 redirect all traffic with WWW to without. ( ->

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

Force WWW

HTTP 301 redirect all traffic without WWW to with ( ->

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$$1 [L,R=301,NC]

Redirect entire domain

Move all traffic of a domain to root of new domain. This will result in a “soft 404” ( ->

RewriteEngine on
RewriteRule ^(.*)$ [L,R=301]

Redirect entire domain but keep link structure

Move all traffic of a domain to new domain but keep link structure. Used when moving domains ( -> .

RewriteEngine on
RewriteRule ^(.*)$$1 [L,R=301]

Performance & Security

Generic caching rules

Add generic/default caching rules (I can’t find the original source but I believe this is from this Gist).

<IfModule mod_expires.c>
ExpiresActive on

# Perhaps better to whitelist expires rules? Perhaps.
ExpiresDefault                          "access plus 14 days"

# cache.appcache needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5)
ExpiresByType text/cache-manifest       "access plus 0 seconds"

# your document html
ExpiresByType text/html                 "access plus 0 seconds"

# data
ExpiresByType text/xml                  "access plus 0 seconds"
ExpiresByType application/xml           "access plus 0 seconds"
ExpiresByType application/json          "access plus 0 seconds"

# rss feed
ExpiresByType application/rss+xml       "access plus 1 hour"

# favicon (cannot be renamed)
ExpiresByType image/x-icon              "access plus 14 days"

# media: images, video, audio
ExpiresByType image/gif                 "access plus 14 days"
ExpiresByType image/png                 "access plus 14 days"
ExpiresByType image/jpg                 "access plus 14 days"
ExpiresByType image/jpeg                "access plus 14 days"
ExpiresByType video/ogg                 "access plus 14 days"
ExpiresByType audio/ogg                 "access plus 14 days"
ExpiresByType video/mp4                 "access plus 14 days"
ExpiresByType video/webm                "access plus 14 days"

# htc files  (css3pie)
ExpiresByType text/x-component          "access plus 14 days"

# webfonts
ExpiresByType font/truetype             "access plus 14 days"
ExpiresByType font/opentype             "access plus 14 days"
ExpiresByType application/x-font-woff   "access plus 14 days"
ExpiresByType image/svg+xml             "access plus 14 days"
ExpiresByType application/ "access plus 14 days"

# css and javascript
ExpiresByType text/css                  "access plus 14 days"
ExpiresByType application/javascript    "access plus 14 days"
ExpiresByType text/javascript           "access plus 14 days"

<IfModule mod_headers.c>
Header append Cache-Control "public"

Noindex an entire folder or subdomain

If you want to keep an entire folder (like /cms/) or entire subdomain (like out of the index you can send a X-Robots-Tag HTTP header.

Header set X-Robots-Tag "noindex, nofollow"

Noindex specific filetypes (images, PDFs, etc)

If you want to keep a specific filetype out of the index you can serve a X-Robots-Tag HTTP header. Useful for images, PDF files, or videos.

<Files ~ "\.(png|jpe?g|gif)$">
  Header set X-Robots-Tag "noindex"

<Files ~ "\.pdf$">
  Header set X-Robots-Tag "noindex, nofollow"

Block visitors by IP (blacklist)

Sends visitors a “403 Forbidden” error based on IP address.

Order Allow,Deny
Deny from 123.456.12.123
Deny from 123.456.21.321
Allow from all

Allow visitors by IP (whitelist)

Send everybody a “403 Forbidden” error except given IP address. Useful for admin areas and development sites.

Order Deny,Allow
Deny from all
Allow from 123.456.12.123


Set site in maintenance mode

Temporary redirect (HTTP 302) all traffic to maintenance.html. Make sure the maintenance page sends a HTTP 503 header.

RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^111.222.333.444
RewriteCond %{REQUEST_URI} !/maintenance.html$ [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteRule .* /maintenance.html [L,R=302]

Error Documents

ErrorDocument 400 /400.html
ErrorDocument 401 /401.html
ErrorDocument 403 /403.html
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html

Useful links


This blog doesn't have a comment section. That doesn't mean I don't want your feedback but I'd rather have a more personal conversation via Email or Twitter.