Useful .htaccess rules for all websites

Category: Blog • Posted by Jeff Starr • Updated:

Here are some of my favorite .htaccess rules that I add to most of my personal sites and client projects. These techniques have been collected and refined over the years, and can help improve the usability, performance, and security of any Apache-powered website.

Note that there are cases where you would not want to add these rules. For example, if you don’t want to enable mod_rewrite, then you wouldn’t want to add the rule that enables it. These rules are all pretty basic and straightforward, but you should understand what each technique is doing before adding to your .htaccess file.

Enable essential core functionality

This first set of rules is what inspired this tutorial. They are added to all of my sites because they enable essential functionality:

# CORE
Options -Indexes
Options -MultiViews
Options +FollowSymlinks
AddDefaultCharset UTF-8
ServerSignature Off
FileETag none

Here is what these rules are doing (in order or appearance):

  • Disable all directory views (recommended for better security)
  • Disable multi-views (recommended for canonical URIs)
  • Enable symlinks (required for permalinks/rewrites, e.g., index.phpindex.html)
  • Specify the default character set for any file served text/plain or text/html (recommended for usability)
  • Disables the server signature (recommended for better security)
  • Disables the ETag Header (recommended for performance)

Note that, depending on your setup, an additional rule may be required to completely disable the ETag Header. See the next section for more information.

Tip: you can combine any Options directives on a single line, for example:

Options -Indexes -MultiViews +FollowSymLinks

Unset ETag Header

This snippet disables Apache’s ETag Header:

# ETAG
<IfModule mod_headers.c>
	Header unset ETag
</IfModule>

This technique can provide a small performance boost on certain configurations. For example, disabling ETag is reported to improve performance on clustered servers. And more generally reduces the overall size of both sent and received HTTP headers.

Enable mod_rewrite

If mod_rewrite is installed on your Apache server, you can make sure it is enabled using the following snippet:

# REWRITE
<IfModule mod_rewrite.c>
	RewriteEngine On
</IfModule>

That needs to be included at least once in order for mod_rewrite to operate.

Enable mod_speling

If mod_speling is installed on your Apache server, you can make sure it is enabled using the following snippet:

# SPELLING
<IfModule mod_speling.c>
	CheckSpelling On
</IfModule>

Once enabled, mod_speling redirects misspelled requests to any nearest matching resources. Uses a bit of memory, but can be useful if you’ve been changing URIs or have lots of similarly named URIs. To disable mod_speling, use this instead:

CheckSpelling off

Enable mod_expires

If mod_expires is installed on your Apache server, you can make sure it is enabled using the following snippet:

# EXPIRES
<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault A300
</IfModule>

That also sets a default expires value of 300 seconds, so go ahead and adjust that value to suit your needs. Once enabled, mod_expires enables caching rules such as these:

ExpiresByType image/x-icon "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"

For more ExpiresByType directives, check out my post over at WP-Mix, Additional file-types for mod_expires.

Add mod_mime suport

The mod_mime module is useful for a wide variety of techniques. Here is a snippet that sets proper MIME types for all files:

# MIME TYPES
<IfModule mod_mime.c>
	
	# DEFAULTS
	DefaultLanguage en
	AddLanguage en-US .html .css .js
	AddCharset utf-8 .html .css .js .xml .json .rss .atom
	
	# JAVASCRIPT
	AddType application/javascript js jsonp
	AddType application/json json
	
	# FONTS
	AddType font/opentype otf
	AddType application/font-woff woff
	AddType application/x-font-woff woff
	AddType application/vnd.ms-fontobject eot
	AddType application/x-font-ttf ttc ttf
	AddType image/svg+xml svg svgz
	AddEncoding gzip svgz
	
	# AUDIO
	AddType audio/mp4 m4a f4a f4b
	AddType audio/ogg oga ogg
	
	# VIDEO
	AddType video/mp4 mp4 m4v f4v f4p
	AddType video/ogg ogv
	AddType video/webm webm
	AddType video/x-flv flv
	
	# OTHERS
	AddType application/octet-stream safariextz
	AddType application/x-chrome-extension crx
	AddType application/x-opera-extension oex
	AddType application/x-shockwave-flash swf
	AddType application/x-web-app-manifest+json webapp
	AddType application/x-xpinstall xpi
	AddType application/xml atom rdf rss xml
	AddType application/vnd.openxmlformats .docx .pptx .xlsx .xltx . xltm .dotx .potx .ppsx
	AddType text/cache-manifest appcache manifest
	AddType text/vtt vtt
	AddType text/x-component htc
	AddType text/x-vcard vcf
	AddType image/webp webp
	AddType image/x-icon ico
	
</IfModule>

This technique does several things:

  • Sets the default language (en)
  • Specifies the correct language for common files (.html, .css, .js)
  • Force UTF-8 encoding for some common file formats (.html, .css, .js, .xml, .json, .rss, .atom)
  • Adds MIME support for a wide variety of commonly used file types

The specific file types added here serve as an example of what’s possible. Basically you can add support for any required file type. And of course, if there is a type added here that you do not need, it is totally fine to remove it. In other words, customize the above code as needed.

Note: if you want to be more specific with the DefaultLanguage, you can use en-US, like so:

DefaultLanguage en-US

Set the default admin email address

There are various scenarios where the server outputs/displays the email address of the server administrator. For example, when there is a 500-level error, the footer of the output HTML page will include the admin’s email in order for users to contact support, etc. The default value for the admin email is taken from the server configuration, but you can customize it on most setups using the following snippet:

# ADMIN EMAIL
SetEnv SERVER_ADMIN email@example.com

Note that it’s best to use a disposable email address for this purpose, as the information is presented in plain text, so spam bots eventually may discover it.

Set the default timezone

If for some reason the timezone set for your server is incorrect, you can modify it using the following snippet:

# TIMEZONE
SetEnv TZ America/Los_Angeles

You can find lists of timezones online, such as this one and the one at Wikipedia.

Set the default directory index

When directory views are enabled, Apache will serve the default index file, which usually is either index.html or index.php. If you want to use a different file, you can customize the default behavior using this snippet:

# DIRECTORY INDEX
DirectoryIndex index.php index.html index.htm

Once in place, this snippet instructs Apache to use index.php if it exists. If it does not exist, then index.html will be used, and so on. You can specify any files in any order to display for directory views. Note that, if this rule is added to the site’s root .htaccess file, it will affect all .htaccess files in all subdirectories. So you can do that or just add directly to a specific directory to apply the rule locally.

Enable Directory Views

In the first section of this article, we see how to disable directory views, which generally is desired and good for security. But there are cases when directory views are desirable (for example, sharing music, images, and other bulk files). Here is the snippet to use to enable directory views:

# ENABLE DIRECTORY VIEWS
Options +Indexes

That should only be added to the specific directory for which you want to allow open views; definitely NOT recommended to include in root .htaccess (unless you know what you are doing).

Ignore certain file types: for directories where views are enabled, you can “hide” specific file types using the following rules:

# IGNORE FILE TYPES
IndexIgnore *.wmv *.mp4 *.avi *.etc

Note: if you are planning on enabling directory views on your site, check out my in-depth article on customizing directory views. It’s just packed with the juicy infos.

Disable PHP Globals

Nice little snippet to disable all PHP Global Variables:

# DISABLE GLOBALS
php_flag register_globals off

Note: this doesn’t work on all configurations. In such cases you can try adding via the Apache configuration file. Ask your host for more information.

Set default rewrite base

If you are using a lot of rewrites, it may be helpful to set the default RewriteBase:

# REWRITE BASE
RewriteBase /

That is to say, if you find yourself including this line in all of your mod_rewrite rules, you can save some space by just declaring it once before all other rewrite rules (e.g., near the top of your .htaccess file).

Go further..

For more tips and tricks for improving the usability, performance, and security of your site, get my book .htaccess made easy. But don’t take my word for it, check out what readers are saying »