Tips for editing .htaccess file

I am creating and editing .htaccess files quite often, at least when I start a new WordPress project. It is very useful to manage, set up and/or protect your web site with a few code lines.

In this article you will find the most useful code snippets often used in a .htaccess file.

If something goes wrong, no problem, instead of your website you will see an ERROR500 message. No problem, just change back to the previous working .htaccess file – I guess you always do a backup, right?

About .htaccess

.htaccess is the default file name of a special configuration file. It provides commands for controlling and configuring the Apache Web Server. It controls and configures modules that can be built into the Apache installation, or included at run-time like mod_rewrite, mod_alias and mod_ssl. Well, I kept the story very short.

Redirecting for SSL certificate

When you will install a SSL certificate, you want all traffic over HTTPS. Sometimes it just works, sometimes you have to force it over a permanent redirect (301) like this:

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R=301,L]

Redirecting, temporary and permanent

This is quite important for SEO and to let you know the search engines what have been redirected and what is the actual link. Permanent redirect is 301, temporary is 302.

So, this allows you to permanently (301) redirect your entire website to any other domain

Redirect 301 / http://yourdomain.com/

Redirecting temporarily (302) is good for SEO purposes when you plan to switch the website back

Redirect 302 / http://yourdomain.com/

Redirecting original links if they are not existing anymore, you decided to provide new or different content with different link (URL address)

Redirect 301 /olddirectory/oldfile.xyz http://yourdomain.com/newdirectory/newfile.xyz

Allow Origin

Sometimes when you are using CDN, or loading custom fonts (or icons), you can see weird characters. To fix it, use

<FilesMatch "\.(ttf|otf|woff)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>

Custom error page 404 Not found

If you created a page with link “not found” for pages which are not existing (non-valid links) you can do redirect – set up custom page. Well, nowadays most of WordPress themes has custom error page built-in.

ErrorDocument 404 errors/yournotfound/

Add Expires headers

It is very useful to set up an expiry time for files (images, attachments, scripts, etc) from the point of seo. The code with seconds for it is

<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault A432000
ExpiresByType text/css A777600
ExpiresByType image/gif A777600
ExpiresByType image/png A777600
ExpiresByType image/jpg A777600
ExpiresByType image/x-icon A777600
ExpiresByType application/x-javascript A777600
ExpiresByType text/plain A777600
</ifModule>

If you are having frequently updated content, set it on 7 days or less, for news can be set 0. I am using for my needs 9 days, it is exactly 777600 seconds.

You can use also this for everything with one time

<ifModule mod_headers.c>
ExpiresActive On
<filesMatch ".(htm|html|css|txt|ico|gif|jpg|jpeg|png|mp4|webm|ogv|woff|eot|svg|ttf|js)$">
Header set Cache-Control "max-age=777600, public, must-revalidate"
</filesMatch>
</ifModule>

Protecting wpconfig.php file

It is good to protect this very important configuration file by restricting access to it.

<files wp-config.php>
order allow,deny
deny from all
</files>

Extra protection against SQL injection

This should be covered by existing WordPress version, but in case you are using some extra stuff on your website, it is not a bad idea also to drop it into a .htaccess file

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]

Something small against robots

SetEnvIfNoCase User-Agent "^libwww-perl*" block_bad_bots
Deny from env=block_bad_bots

Restrict directory listing

It is nobody’s business what is on your server. Some files can be just temporary for testing etc, so it is good to prevent listing files with

Options -Indexes

or

IndexIgnore *

Time zone

For some purposes you want simulate different time zone you can do it with

SetEnv TZ Australia/Sydney

Full list of supported time zones is here.

Force “File Save As…” prompt

Sometime you want users to save some file which is opened by the internet browser by default. You can force the browser to “Save file as…” with a piece of code like

AddType application/octet-stream .avi .mpg .mov .pdf .xls .mp4

Gzip compression

Gzip is normaly enabled already. But if you have web hosting with a company which doesn’t care about services, you may find no gzip compression. If it is supported, you can enable it.

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/html
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>

Protecting .htaccess file

Actually I think it is protected by server already, but an extra piece of code is good too, just in case some plugin can be infected by malware and trying to change the rules.

<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>

Block bad bots

Bad bots are site rippers, spammers, downloaders, etc. With this code/list we will block them. Bad bots will get error page “403 Forbidden”.

RewriteEngine On 
RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Bot\ mailto:craftbot@yahoo.com [OR] 
RewriteCond %{HTTP_USER_AGENT} ^ChinaClaw [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Custo [OR] 
RewriteCond %{HTTP_USER_AGENT} ^DISCo [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Download\ Demon [OR] 
RewriteCond %{HTTP_USER_AGENT} ^eCatch [OR] 
RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [OR] 
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR] 
RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Express\ WebPictures [OR] 
RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro [OR] 
RewriteCond %{HTTP_USER_AGENT} ^EyeNetIE [OR] 
RewriteCond %{HTTP_USER_AGENT} ^FlashGet [OR] 
RewriteCond %{HTTP_USER_AGENT} ^GetRight [OR] 
RewriteCond %{HTTP_USER_AGENT} ^GetWeb! [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Go!Zilla [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Go-Ahead-Got-It [OR] 
RewriteCond %{HTTP_USER_AGENT} ^GrabNet [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Grafula [OR] 
RewriteCond %{HTTP_USER_AGENT} ^HMView [OR] 
RewriteCond %{HTTP_USER_AGENT} HTTrack [NC,OR] 
RewriteCond %{HTTP_USER_AGENT} ^Image\ Stripper [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Image\ Sucker [OR] 
RewriteCond %{HTTP_USER_AGENT} Indy\ Library [NC,OR] 
RewriteCond %{HTTP_USER_AGENT} ^InterGET [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Internet\ Ninja [OR] 
RewriteCond %{HTTP_USER_AGENT} ^JetCar [OR] 
RewriteCond %{HTTP_USER_AGENT} ^JOC\ Web\ Spider [OR] 
RewriteCond %{HTTP_USER_AGENT} ^larbin [OR] 
RewriteCond %{HTTP_USER_AGENT} ^LeechFTP [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Mass\ Downloader [OR] 
RewriteCond %{HTTP_USER_AGENT} ^MIDown\ tool [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Mister\ PiX [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Navroad [OR] 
RewriteCond %{HTTP_USER_AGENT} ^NearSite [OR] 
RewriteCond %{HTTP_USER_AGENT} ^NetAnts [OR] 
RewriteCond %{HTTP_USER_AGENT} ^NetSpider [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Net\ Vampire [OR] 
RewriteCond %{HTTP_USER_AGENT} ^NetZIP [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Octopus [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Explorer [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Navigator [OR] 
RewriteCond %{HTTP_USER_AGENT} ^PageGrabber [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Papa\ Foto [OR] 
RewriteCond %{HTTP_USER_AGENT} ^pavuk [OR] 
RewriteCond %{HTTP_USER_AGENT} ^pcBrowser [OR] 
RewriteCond %{HTTP_USER_AGENT} ^RealDownload [OR] 
RewriteCond %{HTTP_USER_AGENT} ^ReGet [OR] 
RewriteCond %{HTTP_USER_AGENT} ^SiteSnagger [OR] 
RewriteCond %{HTTP_USER_AGENT} ^SmartDownload [OR] 
RewriteCond %{HTTP_USER_AGENT} ^SuperBot [OR] 
RewriteCond %{HTTP_USER_AGENT} ^SuperHTTP [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Surfbot [OR] 
RewriteCond %{HTTP_USER_AGENT} ^tAkeOut [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Teleport\ Pro [OR] 
RewriteCond %{HTTP_USER_AGENT} ^VoidEYE [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Web\ Image\ Collector [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Web\ Sucker [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebAuto [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebCopier [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebFetch [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebGo\ IS [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebLeacher [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebReaper [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebSauger [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Website\ eXtractor [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Website\ Quester [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebStripper [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebWhacker [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WebZIP [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Wget [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Widow [OR] 
RewriteCond %{HTTP_USER_AGENT} ^WWWOFFLE [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR] 
RewriteCond %{HTTP_USER_AGENT} ^Zeus 
RewriteRule ^.* - [F,L]

And now the best tip ever!!!

Actually it is simple: do backup, backup and backup. When something goes wrong, you can always roll back without having nervous breakdown.

Author: Milan Lipowski

Milan is a web designer & developer and stock photographer. He also has over 20 years experience with hardware and software computer servicing for individuals, and small & middle-size companies.