Complete Guide To .HTACCESS – From The Basics To Advanced Learning

Last Update:

Reviewed by Durr E Adan

This post contains affiliate links, and we will be compensated if you buy after clicking on our links.

Read our review guidelines

Controlling the majority of aspects related to the Apache webserver and its variants requires the utilization of the .htaccess file. In this guide, you will learn how to set up special error pages, redirects, password-protect directories, and other related aspects.

Contents show

How to Use This Guide

This guide aims to bring you an exhaustive resource for utilizing the functionalities of .htaccess. If you are a complete novice to using .htaccess, starting with the “.htaccess Basics” below in the first chapter will help you learn better as a beginner.

On the other hand, if you are already aware of the subject and looking for tutorials or certain code samples, you can directly access the sub-section relevant to the topic you are searching for.

.htaccess Basics

Let us discuss some of the fundamental concepts related to .htaccess before learning different commands.

What Is The Meaning Of .htaccess?

A configuration file controls the responses of a server to different requests which we call .htaccess. A lot of web servers are compatible with the .htaccess file, including the Apache server that is used by many web hosts.

All .htaccess files work at the directory level and can override the configuration settings, at a global level, of all those .htaccess directives that have a place above them in the main directory tree.

How To Use .htaccess?

.htaccess is commonly used for securing websites or web pages by enabling password protection, redirecting URLs, boosting SEO using trailing slashes for URLs, and building custom error pages like the 404 error page.

For the SEO aspect, the webmaster chooses either to use or avoid using a trailing slash at the end of website URLs. Maintaining consistency in the use of trailing slashes helps boost SEO.

From where does the name .htaccess originate?

.htaccess is an abbreviation that expands to “HyperText Access”. The tool was originally utilized for controlling the access of users to the desired files on each directory, which led to this name.

A system administrator becomes capable of restricting access to the desired directories by using the httpd.conf settings of Apache via .htaccess. The administrator can specify the names and passwords of directory users in a corresponding .htpasswd file.

This was only the initial use of .htaccess files and today they are used for many other purposes too along with this initial functionality. We’ll cover these additional functions of .htaccess files in this detailed guide.

Where Is the .htaccess File?

Each folder of the server, theoretically, might have one .htaccess file. But, usually, you will find one .htaccess file in the folder carrying all of your website content i.e the root folder of your server. Such a folder is either labelled as www. or public_html.

When your website has multiple subdirectories under one directory, the .htaccess file usually lies in each of the subdirectories and also the root directory. The subdirectories are generally labeled as /sitename.

Why Am I Unable To Find .htaccess File?

There are “hidden files” in many file systems. Such files have a dot ( . ) at the beginning of their names and are generally hidden under the default settings.

However, you can find these hidden files easily by looking for an option of “show hidden files” in your File Manager or FTP client. This option sits at different places depending on the program you are using. You can find it under “Settings”, “Preferences”, “Folder Options” or “View”.

What If My Website Does Not Have a .htaccess File?

You must first ensure that you do not have a .htaccess file by turning on the “show hidden files” option. Generally, these files are automatically created, so there are high chances that you might have one. However, in some cases, this might not be true.

You can create a .htaccess file by following these steps if you do not have one:

  • Open the “plain text” editor for creating a new file.
  • Save this newly created file in the ASCII format as .htaccess. While doing so, ensure that there aren’t any file extensions like .htaccess.txt and similar.
  • Now upload this newly created .htaccess file to the desired directory via File Manager or FTP.

Error Handling

Error handling is among the easiest tasks that can be achieved by specifying error documents using different .htaccess files.

What Is an Error Code?

A server will try responding to every request it receives. When the request comes from HTML pages, a document is delivered in response. On the other hand, when the request comes from a Content Management System or any other application, the webserver accesses the app and returns the output.

If the webserver is unable to respond to a request, an error gets generated. Individual error codes have been allotted to different kinds of errors. You must have encountered 404 errors online which are returned when the server is unable to find the document.

Apart from that, a server can return other numerous error codes, some of which are listed hereunder:

Server Errors

  • 500 — Internal Server Error
  • 501 — Not Implemented
  • 502 — Bad Gateway
  • 503 — Service Unavailable
  • 504 — Gateway Timeout
  • 505 — HTTP Version Not Supported.

Client Request Errors with their definitions

  • 400 — Bad Request
  • 401 — Authorization Required
  • 402 — Payment Required (not used yet)
  • 403 — Forbidden
  • 404 — Not Found
  • 405 — Method Not Allowed
  • 406 — Not Acceptable (encoding)
  • 407 — Proxy Authentication Required
  • 408 — Request Timed Out
  • 409 — Conflicting Request
  • 410 — Gone
  • 411 — Content Length Required
  • 412 — Precondition Failed
  • 413 — Request Entity Too Long
  • 414 — Request URI Too Long
  • 415 — Unsupported Media Type.

Default or Generic Error Handling

When it is not specified how to handle a specific error type, the server returns a default message and the browser then shows a generic message for all the unspecified errors. So, it is best to specify different errors.

How To Specify Error Documents?

You can handle errors by generating HTML documents for the error codes you wish to manage. To make them easier to remember, consider naming these HTML documents as to what these errors denote. For instance, name the document related to the 404 error as 404.html or not-found.html.

Once you are done with the HTML document generation part, specify the ones that the server should use corresponding to different kinds of errors. For instance, in a .htaccess file, such specifications will look like this:

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

You must have noticed that a single directive occupies a single line to keep it simple. That’s it, you have learned it all.

.htaccess Alternatives For Handling Errors

Most web applications, WordPress, Drupal, and other CMS have their unique methods to handle these codes.

Password-Protecting Files Via .htaccess

.htaccess files were first created only to put restrictions on accessing some, or the other directories based on a specific user (thus got hypertext access as its name). Let us understand that part first:


All the usernames with their respective passwords for their corresponding .htaccess data are saved in a separate file named .htpasswd

Every single line has each one of it in the following form:


Say, for instance:


That being said, the password that is stored in the respective file does not happen to be the real password needed for logging in. But it is what is called any password’s cryptographic hash.

To make it simpler, it is just encryption of a real password obtained by running the actual password through the encryption algorithm. The resultant password obtained is, thus, stored. While logging in every time, the user enters a password in the plain text which is churned through that encryption algorithm. The passwords tally when the plain-text input is correct, allowing the user to access the files.

This is termed as the more secure way of storing passwords; the reason being, for anyone attempting to break into your .htpasswd data file, all they would get is a hashed password instead of the original one. And it is impossible to obtain the original password by using the hash one as the encryption works only one way- from original to hash.

There are many hashing algorithms for securing the passwords:

Secure hashing algorithms – It is advised to use any of the following

  1. bcrypt- Though painstakingly slow for hashing, it is the best option for security. It is backed by Nginx and Apache.
  2. md5- Apache uses this one as the default algorithm for hashing passwords currently. Nginx does not back it.

Insecure hashing algorithms- It is advised not to use the following ones:

  1. crypt()- It cannot be called a secure algorithm as it uses a default hashing rule.
  2. SHA along with Salted SHA are both termed as insecure.

Creating Passwords and Usernames over Command Line

With an SSH terminal or Command-Line, one can directly create a .htpasswd file. Pair it up with their respective username and passwords easily.

The .htpasswd data file can be made by using a simple command htpasswd.

Use this command over the -c (create) option for creating a brand new .htpasswd file. The next step is to type the directory path. The path should not be the URL but the server’s actual path.

It also lets you add a user if you wish to.

> htpasswd -c /usr/local/etc/.htpasswd willyjones

A new file would, then, be created in the /etc/ directory with a record of the user ‘willyjones’. A prompt will, then, require you to add a password, and this password will be recorded with the encryption md5.

When a .htpasswd file already exists at a specified location, you will not be able to create a new file. However, it will be added to the already existing file under a new user name.

If you wish to utilize the bcrypt algorithm instead of the md5 hashing algorithm, swap the –c option with –b option.

Hashing password without using Command Line

In case, you do not have access to an SSH terminal, command line, or are uncomfortable using it, create a .htpasswd data file and fill it with the help of a simple text editor. Then simply upload it with a file manager or FTP.

But having taken that route, you would have to encrypt all the passwords yourself as, otherwise, a htpasswd command has been doing that job for you.

For encrypting your password, use one of the many .htpasswrd encrypting utilities accessible online. However, the best one happens to be the htpasswd generator available at here.

It offers you multiple options to set password strength and choose hashing algorithm. Simply copying the output generated and pasting it to the .htpasswd data file would help.

Where to store the .htpasswd data file?

There is no need to keep individual .htpasswd data files for all the corresponding .htaccess files. The truth is that you should avoid doing it at all. Normally, you should keep just a single file for your main server directory or the entire hosting account.

Also, a .htpasswd data file shall never be stored in a directory that can be accessed publicly. In other words, it should not be in www or public_html or a subdirectory. Rather it shall always be in a folder above any of these that can be accessed only from the main server.

Using .htpasswd over .htaccess

Every directory can be associated with a unique .htaccess file of its own and a user group that has access to it.
Any of the users, including the ones that are not logging in, have default access to this directory plus all its files.

To restrict any user’s access to the .htaccess file, the following code can be used:

AuthUserFile /usr/local/etc/.htpasswd
AuthName "Name of Secure Area"
AuthType Basic

require valid-user

The file name and the path where the list of your passwords and usernames are stored create the first line. The next line mentions the name for the new secured area. You can fill any secure path here. The next line has an authentication type; ‘Basic’.
The tag in the fourth line specifies the restrictions being added. Here, the access to POST or GET any file from the said directory is being shown. And within the tag, a user list for allowing access to the files is added.
To sum up the above scenario, any user that has been added to the directory can access the files. In case you wish to stop or restrict one or a few users, add the specific name/names:

AuthUserFile /usr/local/etc/.htpasswd
AuthName "Name of Secure Area"
AuthType Basic

require user willyjones
require user jamessmith

Another way to grant access is to group all the users and grant access to the group. Add a file that mentions the group/groups and their respective users to exercise this option.
You can also name this group file .htgroups which looks like this:

admin: willyjones jamessmith
staff: jamessmith tinacorden

The next step is to add them to the .htaccess datafile:

AuthUserFile /usr/local/etc/.htpasswd
AuthGroupFile /usr/local/etc/.htgroup
AuthName "Admin Area"
AuthType Basic

require group admin

.htpasswd file alternatives

Restricting access to specific files on the main server using .htpasswd and .htaccess is feasible only when you have got multiple files that are, static. The necessity to have this feature can be traced back to the times when websites were nothing but a bunch of HTML pages and other such resources.

Today, the process of restricting and granting access to files has become easier with CMS or Content Management Systems like Drupal or WordPress. If you are one of the users of CMS, simply utilize the special in-built features meant to do the task easily.

How To Enable Server Side Includes?

Let us find out the meaning and usage of Server Side Includes.

The Meaning Of SSI

Server Side Includes or SSI is a scripting language that helps in embedding HTML documents or common codes to other documents. SSI allows the reuse of common elements like menus, sidebars, headers, and footers. Content Management Systems and website templates that we use today can be thought to have originated from SSI.

<!-- include virtual="header.shtml" -->

Variables and conditional directives like else, if, etc. are also a part of SSI. This aspect makes it a fully complete scripting language but at the same time makes it tougher. So a developer will certainly go for a robust and easier language like Perl or PHP if a project involves quite a large number of “Includes”.

How to Enable SSI?

In some cases, SSI is default-enabled by a web hosting server while this might not be true at all times. So, it can be enabled through the .htaccess file in this manner:

AddType text/html .shtml
AddHandler server-parsed .shtml
Options Indexes FollowSymLinks Includes

SSI for files with the extension .shtml will be enabled by the above code.

Enabling SSI Over The .html Files

The following directive can be added when enabling SSI on your .html datafiles:

AddHandler server-parsed .html

This above-mentioned code will parse the HTML files thereby allowing you to utilize SSI and its features, without the world knowing its usage. Additionally, it provides you with the benefit of keeping the HTML data file extensions even if you alter any implementations later.

But this general parsing of all your HTML files also has a major disadvantage. It will lead to unnecessary server overhead which, in turn, will consume CPU resources and negatively impact your page load times as well. So it is advised not to parse all your HTML files when it is not needed.

SSI On The Home Page

.htaccess file can help you use SSI only on the website’s home page when you decide against parsing all the HTML files.

By default, the webserver looks for the index.html file when finding your home page. So if you choose not to parse any HTML files, consider naming your home page as index.shtml so that SSI functions properly.

You will have to add the following code to achieve do that and let your server know where to find your home page:

DirectoryIndex index.shtml index.html

The above code informs the server that your main index file is index.shtml while index.html can be used only as a backup when the primary file is inaccessible.

IP Whitelisting and IP Blacklisting

.htaccess can be used to restrict user access to your server. Such restrictions can be of two types:

  • IP Blacklisting
  • IP Whitelisting

Let us understand their meanings before knowing how to attempt the restrictions.

How to perform IP Blacklisting?

The following code will help you block the desired IP addresses. Don’t forget to replace the IP addresses with the ones you want to blacklist:

order allow,deny
deny from
deny from 789.56.4.90
allow from all

In the above code, the very first line directs the server to evaluate the allow code first and the deny code thereafter. So all the traffic will be allowed by considering the allow from all code first. Then the IP addresses corresponding to the deny code will be blocked.
It is important to write this line in the same order because if it is reversed and written as order deny,allow, the allow directive will then override all the deny directives. It will nullify all the deny directives.

Also, you can block a full block of IP addresses that are creating problems. In the above code, the 3rd line does not include a complete address but the block. So all the IPs belonging to that block will be denied access to your website.
The deny from directive can be used to block any number of IP addresses while including one per line.

How to perform IP Whitelisting?

Whitelisting is the exact opposite of blacklisting i.e. restricting all the visitors except a few desired IP addresses.

You must have guessed by now that the code will involve the reversal of the directive to deny everyone first and allow only the ones mentioned.

The following code will help you whitelist a few desired IP addresses. Don’t forget to replace the IP addresses with the ones you want to whitelist:

order deny,allow
deny from all
allow from
allow from 789.56.4.90

Blocking Actions

.htaccess allows you to block scrapers and bots by domain or referrer. Let us get deeper into the processes of both:

Blocking Users By Domain

Blocking visitors by domain is quite beneficial when you do not want a specific domain to bother you by changing its IP address.

But such a type of blocking is not functional when the user is capable of controlling his reverse-DNS mapping for the IP address.

The following code will allow you to block users by domain:

order allow,deny
deny from
allow from all

The above code works both for the main domain and its subdomains. So the traffic from also gets blocked.

Blocking Users using Referrer

Any website carrying a page link to your website is called a referrer when the visitor follows that link and comes to your site. Blocking by referrer does not function when a referrer is carrying hyperlinks that are, clickable.

Another important thing to understand before using this method is hotlinking. When an internet page links to pictures posted on your website, it is known as hotlinking. This practice consumes your account bandwidth plus it might even lead to copyright infringement without sending any traffic to your site.

In addition to pictures, such hotlinking can also be done with JS scripts, CSS files, or other such resources on your website. Though the majority of website owners do not bother about such hotlinking, however in some cases, it might seem abusive.

Also, sometimes clickable hyperlinks included in the text become troublesome like the ones included on hostile websites. When you are facing the above-mentioned problems, you can resort to blocking users by the referrer technique.

For using this code, your mod_rewrite module must be enabled. Generally, it is default-enabled by hosting providers but you must confirm it from your host before moving forward. If your host informs you that it is not enabled and cannot be done, you must consider changing your host to perform this function.

.htaccess code related to blocking by referrer works only with mod_rewrite.
You can use the following code for blocking traffic by using referrer:

RewriteEngine on
RewriteCond % ^http://.* [NC,OR]
RewriteCond % ^http://.* [NC,OR]
RewriteCond % ^http://.* [NC]
RewriteRule .* - [F]

It is a bit complicated, so let us understand it in detail here:

  • The very first indicates that rewrite-related directives will follow.
  • The second, third, and fourth lines block certain specific domains and you will have to replace the domain names (like with the ones you want to block.
  • Escape characters in the form of backward slashes have been used in the code above. The dot that we use in the code refers to something contained in RegEx and it must be escaped with a backward slash.
  • The NC and OR used in brackets also denote certain directives. NC indicates that the corresponding matches are case insensitive. And the OR denotes the simple “or” which means that this rule is followed by another rule and so on. That is why you will notice that the last line does not include the OR directive.
  • The closing line in the above code denotes the rewrite rule. [F] in this line refers to Forbidden. So all the referrers that you mention before this line will be forbidden and receive a 403 Client Request Error.

Blocking Scrapers and Bots

All website managers have to deal with the most annoying visitors to their sites i.e. bots, scrapers, and crawlers. They all eat up your bandwidth without benefitting you in any manner.
Such acts are performed to extract some information from your website and republish it following a cheap SEO practice.

Some bots are legitimate ones too, like the ones that belong to search engines. However, the majority of bots are unnecessary and can be compared to pests that consume your resources without providing any advantage to you.

Hundreds of bots have been identified and many originate over time. So it is impossible to block them all but their activity can be minimized by blocking the ones you can identify.

You can use the rewrite rules compiled at the following link from AskApache and successfully block over 400 bots that have already been identified.

How To Specify Default File?

When a URL has not specified a name for a file, most servers assume the request is being made for accessing the directory.

That is why Apache and many other servers will try to find the default file in the website’s root directory when a request for is made.

By default, this file looks like index.html. It is because, in the initial internet years, the websites were made to display documents. The main page of a website was merely used for indexing all the documents contained in that website.

But you can alter this default setting if you do not desire to have index.html as your website’s default page or when you do not want to call your website homepage an index page. Let us learn how you can specify a default file for your directory.

How To Set A Default Page For The Directory?

The following code can be used to set a default page for your directory via .htaccess:

DirectoryIndex [filename here]

You can fill in any file name to make it a default page for your directory. So if you desire to set your website homepage as the directory default page, you will write this code:

DirectoryIndex home.html

How To Set Numerous Default Pages?

It is possible to set multiple default pages for your directory. The following code will help you set such multiple default pages:

DirectoryIndex index.php index.shtml index.html

When you set multiple default pages, the server will first look for the very first page for displaying it as the default one. In case it is unable to find that page, it will search for the next page included in the code, and this will go on.

Are you thinking about the need of doing this?

You already know that .htaccess impacts its main directory and all the subdirectories contained therein. And each subdirectory might consist of individual default page names.

When you add such a code to a .htaccess datafile of your root directory, you can prevent the need to add these rules at each directory level. Adding the code in the root directory will make your task easier since it will impact all the directories and subdirectories.

Redirecting and Rewriting URL

The commonest use of a .htaccess file can be found in URL redirects.

Whenever the URL belonging to a resource or document is changed, URL redirecting is put to action. The feature is most useful when a domain name is changed or a website is reorganized.

301 vs. 302 Redirects

The server can generate numerical error codes 301 and 302 on some occasions and these are considered as redirects by the browser.

301 stands for “Permanently Moved” whereas 302 stands for “Moved Temporarily”. You are advised to utilize 301 in most cases as it preserves the SEO equity of the old URL and maps it to your newly created page.

It also prompts most of the browsers to perform certain actions like updating their bookmarks and caching the mapping of new-from-old. Thus, whenever a user or a link tries to access the original URL, the browsers will simply furnish the newly created URL. This is exactly the result you’d desire, had the URL been changed permanently.

302 redirects are rarely used since one hardly changes a URL temporarily. There seems to be logic behind changing one’s URL permanently, though it is not advised. But a temporary change with a pre-planning of bringing it back to the old one seems to be a weird idea that must be avoided at all costs.

The examples mentioned in the following section hereafter will be using the commonest redirect, which is 301.

Redirect v/s Rewrite

To “change” any URL that has .htaccess directives, one can choose one of the following two ways:

  • Redirect Command.
  • mod_rewrite engine

When a redirect command is used, a special message is sent to your browser specifying the URL to search for redirecting.

Usually, mod_rewrite tends to “translate” a single URL (the requested one) to something that can be easily understood by the CMS or your file system. It, then, processes the request of a translated URL the same way the requested one would have been processed.
This typical way of translation goes unnoticed by the browser as if nothing happened and it is simply provided with the content page it requested.

You can also generate 301 redirects using the mod_rewrite tool. It works just like the above-discussed redirect command plus provides an added set of options to set rules. That is to say that mod-rewrite can perform tough pattern matching while offering varied rewriting commands, that cannot be performed by the redirect command.

Redirecting a Basic Page

The following code can be used to redirect a page to a different URL:

Redirect 301 /relative-url.html

The above command can be understood in its four parts that are put in a single line but separated with single space:

  • The first part is the command of redirect
  • The next part specifies the redirection type (301 here means “Moved Permanently”)
  • The third part is the relative or corresponding URL of the previous (old) page
  • And last part is the full URL belonging to the intended (newly created) page

A ‘Relative” URL is the one corresponding to that directory that contains your .htaccess datafile. It usually is the root directory or webroot.

Hence if is shifted to, the following code will be used:

Redirect 301 /blog.php

Redirect a huge section of your website

When you shift your whole directory while keeping the names of your pages intact, the best option is redirecting all the requests for that directory:

Redirect 301 /old-directory

Redirect the entire site

To move your entire site to a brand new URL, use the following code:

Redirect 301 /

How To Redirect www traffic to a non-www page?

Many website owners have stopped using the famous www subdomain these days.

www denotes the world wide web and its usage in the website name started in the initial days of the internet. It wasn’t necessary to use it but people continued its use from the time when websites were used for storing personal documents and sharing them on the internet via the world wide web.

Now, many website owners have stopped using it but some internet users have the habit of typing www. at the beginning of a URL, they are looking for. And when your website is skipping the use of www, ensure that such visitors do reach your website.

For this code, you must ensure that mod_rewrite is installed by default by your hosting provider. Use the following code to redirect www to non-www:

Options +FollowSymlinks
RewriteEngine on
RewriteCond % ^ [NC]
RewriteRule ^(.*)$$1 [R=301,NC]


Many mod_rewrite and .htaccess guides provide you with a variation to this code which is:

Options +FollowSymlinks
RewriteEngine on
RewriteCond % !^ [NC]
RewriteRule ^(.*)$$1 [R=301,NC]

Can you identify the problem in this variation?

It redirects all subdomains to the primary domain. So not just, but also and and anything else. This is probably not the behavior you want.

Redirecting to www

But what if you are using the www subdomain?

You should probably set up a redirect to make sure people get to where they’re trying to go. Especially now that fewer people are likely to automatically add that www to the beginning of URLs.

You just reverse the above code.

RewriteEngine On
RewriteCond % ^ [NC]
RewriteRule ^(.*)$1 [R=301,NC]

Should I Redirect 404 Errors to the Homepage?

Several guides on .htaccess redirects include instructions on how to make 404 errors redirect to the home page.

This is a good example of how just because you can do something, it doesn’t mean you should do something.

Redirecting 404 errors to the site’s homepage is a terrible idea. It confuses visitors, who can’t figure out why they are seeing the front page of a site instead of a proper 404 error page.

All websites should have a custom 404 page which clearly explains to the user that the content couldn’t be found and, ideally, offers some search features to help the user find what they were looking for.

Why Use .htaccess Instead of Alternatives?

You can set up redirect in PHP files, or with any other type of server-side scripting. You can also set them up within your Content Management System (which is basically the same thing).

But using .htaccess is usually the fastest type of redirect. With PHP-based redirects, or other server-side scripting languages, the entire request must be completed, and the script actually interpreted before a redirect message is sent to the browser.

With .htaccess redirects, the server responds directly to the request with the redirect message. This is much faster.

You should note, though — some content management systems actually manage redirects by updating the .htaccess programatically. WordPress, for example, has redirect plugins that work this way. (And WP’s pretty URL system does this as well.)

This gives you the performance of using .htaccess directly, while also giving you the convenience of management from within your application.

Hiding Your .htaccess File: Security Considerations

There is no reason that someone should be able to view your .htaccess file from the web.

Moreover, there are some big reasons you should definitely not want people to see your .htaccess file.

The biggest issue is that if you are using an .htpasswd file, its location is spelled out in the .htaccess file. Knowing where to find it makes it easier to find.

Moreover, as a general rule, you don’t want to provide the public with details about your implementation.

Rewrite rules, directory settings, security — all of the things that you use .htaccess for — it is a good security practice to hide all of this behind-the-scenes at your web server. The more a hacker can learn about your system, the easier it is to compromise it.

It is very easy to hide your .htaccess file from public view. Just add the following code:

<Files .htaccess>
order allow,deny
deny from all

Enabling MIME types

MIME types are file types. They’re called MIME types because of their original association with email (MIME stands for “Multipurpose Internet Mail Extensions”). They aren’t just called “file types” because MIME implies a specific format for specifying the file type.

If you’ve ever authored an HTML document, you’ve likely specified a MIME type, even if you didn’t know it:

<style type="text/css" src="/style.css?x96620" />

The type attribute refers to a specific MIME type.

MIME types on Your Server

Sometimes you’ll find that your web server isn’t configured to deliver a particular type of file. It just doesn’t work — requests for the file simply fail.

In most cases, you can fix this problem by adding the MIME type to your .htaccess file.

AddType text/richtext rtx 

This directive has three parts, each separated by a space:

  • The AddType comman
  • The MIME type
  • The file extension.

If you want to associate several different file extensions with the same MIME type, you can do that on a single line.

AddType image/jpeg jpeg jpg jpe JPG 

Force Download by MIME Type

If you want all links to specific file types to launch as downloads, instead of being opened in the browser, you do that with the MIME type application/octet-stream, like this:

AddType application/octet-stream pdf

Again, you can specify multiple file extensions with a single type:

AddType application/octet-stream pdf doc docx rtf

List of File Extensions and MIME Types

Here is a not-quite-complete list of file formats and associated MIME types.

If you are managing your own website, and you know what file types you publish resources in, then there is no need to paste this entire list into your .htaccess file.

However, if you run a site that many other people are contributing and publishing content to, you may want to simply allow a large number of file types this way to make sure no one has a bad experience.

This is especially the case if you run a site where people might be specifically sharing a lot of files, for example a file sharing site, a project management application (where many files will often be attached to project), or a web app that handles email.

AddType application/macbinhex-40 hqx
AddType application/x-bcpio bcpio
AddType application/x-cpio cpio
AddType application/x-csh csh
AddType application/x-director dcr
AddType application/x-director dir
AddType application/x-director dxr
AddType application/x-dvi dvi
AddType application/x-gtar gtar
AddType application/x-hdf hdf
AddType application/x-httpd-cgi cgi
AddType application/x-latex latex
AddType application/x-mif mif
AddType application/x-netcdf nc cdf
AddType application/x-onlive sds
AddType application/x-ustar ustar
AddType application/x-wais-source src
AddType application/x-sh sh
AddType application/x-shar shar
AddType application/x-sv4cpio sv4cpio
AddType application/x-sv4crc sv4crc
AddType application/x-tar tar
AddType application/x-tcl tcl
AddType application/x-tex tex
AddType application/x-texinfo texinfo texi
AddType application/netalive net
AddType application/netalivelink nel
AddType application/octet-stream bin exe
AddType application/oda oda
AddType application/pdf pdf
AddType application/postscript ai eps ps
AddType application/rtf rtf
AddType application/zip zip
AddType audio/basic au snd
AddType application/x-troff t tr roff
AddType application/x-troff-man man
AddType application/x-troff-me me
AddType application/x-troff-ms ms
AddType audio/x-aiff aif aiff aifc
AddType audio/x-midi mid
AddType audio/x-pn-realaudio ram
AddType audio/x-wav wav
AddType image/gif gif GIF
AddType image/ief ief
AddType image/jpeg jpeg jpg jpe JPG
AddType image/tiff tiff tif
AddType image/x-cmu-raster ras
AddType image/x-portable-anymap pnm
AddType image/x-portable-bitmap pbm
AddType image/x-portable-graymap pgm
AddType image/x-portable-pixmap ppm
AddType image/x-rgb rgb
AddType image/x-xbitmap xbm
AddType image/x-xpixmap xpm
AddType image/x-xwindowdump xwd
AddType text/html html htm
AddType text/plain txt
AddType text/richtext rtx
AddType text/tab-separated-values tsv
AddType text/x-server-parsed-html shtml sht
AddType text/x-setext etx
AddType video/mpeg mpeg mpg mpe
AddType video/quicktime qt mov
AddType video/x-msvideo avi
AddType video/x-sgi-movie movie
AddType x-world/x-vrml wrl 

Block Hotlinking

Hotlinking is the practice of linking to resources from other domains instead of uploading the content to your own server and serving it yourself.

Say you find an image on a website that you really like, and you want to use it on your site. Ignoring copyright issues for the moment — you could download the image, upload it to your website, and embed it on your page like normal.

<img src="">

But if you were lazy, or trying to save bandwidth, or didn’t know how to upload a file, you could just embed it directly form the original file.

<img src="">

That’s hotlinking. It also happens with CSS and JS files, but images are the most common.

Some websites/hosts don’t mind at all if you do this — you can hotlink images from Wikipedia without anyone being upset. And some websites encourage it in one form or another.

For example, JQuery provides their JS libraries via a CDN (Content Delivery Network), so you can hotlink directly to it without having to upload it and serve it from your own server.

But many web host consider hotlinking to be a form of bandwidth and resource stealing.

To be sure, if you are running a relatively small site, you can’t afford to have thousands, or tens of thousands, of requests being made every day for resources that have nothing to do with actual visitors to your site.

If you are having a problem with hotlinking, you can disable it with some mod_rewrite rules added to your .htaccess file.

RewriteEngine on
RewriteCond % !^$
RewriteCond % !^http://(www.)?*$ [NC]
RewriteRule .(gif|jpg|jpeg|png|js|css)$ - [F]

Be sure to change in the third line to your actual domain name. This will catch any requests not coming from your domain, and then check if it matches one of the specified file extensions in the fourth line. If there is a match, the request fails.

If you want to add other file extensions, you can simply edit the last line.

Serving up Alternative Content

If you want to let the world know why their hotlinking has suddenly stopped working, you can replace hotlinked images with a special image with a message like, “We hate hotlinking!” or “Original Content Available at”.

Instead of failing the request, you simply redirect it to the “special” image:

RewriteEngine on
RewriteCond % !^$
RewriteCond % !^http://(www.)?*$ [NC]
RewriteRule .(gif|jpg)$ [R,L]

If you really want to mess with people, you can redirect JavaScript or CSS files to special alternatives that may have unfortunate effects for the hotlinker. This is not recommended, however.

RewriteEngine on
RewriteCond % !^$
RewriteCond % !^http://(www.)?*$ [NC]
RewriteRule .(js)$ [R,L]

RewriteEngine on
RewriteCond % !^$
RewriteCond % !^http://(www.)?*$ [NC]
RewriteRule .(css)$ [R,L]

Disable or Enable Index

What happens if you have a directory full of documents or other resources, no index.html file, and no default directory page specified in the .htaccess file?

In many cases, the result will be a generic directory listing of all the files in the directory.

That’s right. If you have a folder in your hosting directory labeled /images, and it has no index.html page, when someone navigates to, they will be able to see a list of all the images on your site.

That’s the default behavior of most web servers, and it makes sense from the standpoint of the original conception of a website as simply a place to keep and share documents. But this is not the desired behavior for most sites.

Disabling Indexes

Many web hosting accounts will have disable this already as part of their global configuration. But not all do so.

If you need to disable automatically generated directory listings, doing so is easy:

Options -Indexes

Enabling Indexes

If your web server has disabled indexes as part of global configuration, but you do want them, you can enable them with the reverse of the above command.

Options +Indexes

Hiding some files from the Index

If you want to show directory listings, but you want to hide certain file types from the list, you can do that too.

IndexIgnore *.gif *.jpg

The * is a wild-card chracter. The above directive will hide all files that have a .gif or .jpg extension. If you wanted to be more specific, you could:

IndexIgnore secret-image.jpg

Enabling CGI Everywhere

CGI, or Common Gateway Interface, is a server-side method for including non-HTML scripts (like Perl or SSI) in web pages.

Typically, CGI scripts are stored in a folder labeled /cgi-bin. The webserver is configured to treat any resource in that directory as a script, rather than a page.

The problem with that is two-fold: URLs referencing CGI resources need to have /cgi-bin/ in them, which places implementation details into your URL — an anti-pattern to be avoided for a number of reasons.

A complex website may need a better organization structure than simply having a ton of scripts jammed into a single /cgi-bin folder.

If you want your web server to parse CGI scripts no matter where they are found in your directory structure, just add the following to your .htaccess file:

AddHandler cgi-script .cgi
Options +ExecCGI 

If you have other file extensions you want processed as CGI scripts, you can add them in the first line.

Scripts as Source Code

Most of the time, you put scripts in your web directory because, well, you want them to be run as scripts.

But sometimes that isn’t what you want. Sometimes you want to display the source code to public visitors, instead of running the script.

This might be the case if you run a file sharing service or a code repository site, and you want people to see the source code and be able to download it, but the scripts are actually part of your site’s functionality.

This can be done in your .htaccess file by removing the script handler for certain file types and replacing it with a handler for text.

RemoveHandler cgi-script .pl .cgi .php .py
AddType text/plain .pl .cgi .php .py 

Alternatively, as mention previously, you could force files with these extensinos to be downloaded automatically, rather than displayed.

RemoveHandler cgi-script .pl .cgi .php .py
AddType application/octet-stream .pl .cgi .php .py 

Be careful with either of these, though. If you only want some files to be displayed this way, but are still using these scripts for the rest of your website, your going to have a bad time if you put that directive into your web root’s .htaccess file.

A better practice would be to place all such “display only” scripts into a single directory, and then place the directive into an .htaccess file there in that folder.

Configuring PHP Settings

Sometimes you need to tweak PHP’s settings. The right way to do this is in a file called php.ini.

Unfortunately, not all web hosting companies allow their customers to edit the php.ini file. This is especially true of shared hosting providers, where a single installation of PHP may be running hundreds of web sites.

Fortunately, there’s a workaround — you can embed php.ini rules into your .htaccess file.

The syntax looks like:

php_value [setting name] [value]

So, for example, if you need to increase the max file upload size (a common issue), it is as easy as:

php_value upload_max_filesize  10M

Not all PHP settings can be specified in .htaccess files. For example you can not disable_classes this way.

For a complete list of all php.ini settings, see the official php.ini directives guide.

How to Prevent Access to Your PHP include Files

There are several ways to prevent unauthorized access to your PHP includes files.

First, you can put them into a directory and set your .htaccess file to deny all access to that directory (ie, Deny from all if you’re using the Apache HTTP Server). If someone does try to access the file, they will receive an HTTP 403 Forbidden response.

Alternatively, you can store these files outside the directory from which your website files are served. That is, if your webserver is serving files located in /srv/home, you can put your include files under /srv/home/includes. This makes the files inaccessible via URLs, though you can access and use them as follows: include 'PATH_TO_YOUR_FILE'

Finally, you can define a URL constant for the files you want accessible:

define('WEBSITE_URL', '');

Then, for the files that you don’t want accessed, include the following check:

if(!defined('WEBSITE_URL')) {
    header($_SERVER["SERVER_PROTOCOL"] . "403 Forbidden");

How to Prevent Access to Your PHP ini Files

The way to prevent unauthorized access to your ini files is to edit your .htaccess file to deny access to the ini files (ie, Deny from all if using Apache).

How to Set Your Server’s Time Zone

You can set your server’s time zone by specifying it in your .htaccess file. To do so, you will need to add the following line:

php_value date.timezone 'Region/Zone'

Make sure to replace Region/Zone with the time zone you’d prefer.

Save your file. You can test your changes by creating a PHP test file containing the following in the same directory as the .htaccess file:

<?php phpinfo(); ?>

Load the file in your browser, and search for the name of the directive – its Local Value column should display your new time zone setting.

When Not to Use .htaccess

Editing your .htaccess file for the first time can give you sudden feeling of immense power over your web hosting environment. You suddenly feel like a sysadmin.

Unfortunately, this power can go to your head, and you may find yourself using the .htaccess file in ways that aren’t really the best.

When you need to do something that seems like an .htaccess sort of job, there’s basically two situations where you should put that directive somewhere else.

Further Upstream

Whenever possible, the types of directives you can place in an .htaccess file are better off being place in the httpd.conf file, which is a configuration settings file for the entire server.

Similarly, PHP settings more properly belong in the php.ini file, and most other languages have similar configuration setting files.

Placing directives further upstream, in the httpd.confphp.ini, or other language-specific configuration file allows those settings to be “baked-in” to the web server’s parsing engine. With .htaccess, the directives have to be checked and interpreted with every single request.

If you have a low traffic site with only a handful of .htaccess directives, this isn’t a big deal. But if you have a lot of traffic, and a lot of directives, the performance lag can really add up.

Unfortunately, many shared hosting providers do not allow customers to access the httpd.conf or php.ini files, forcing users to rely on the slower .htaccess file.

This provides a double-penalty when compared to custom VPS configurations because shared hosting is also generally low-powered. This is one of the reasons that a site with respectable traffic should probably be on a VPS plan instead of shared hosting plan.

Further Downstream

If you are using a good Content Management System (CMS) such as WordPress or Drupal, some of the things you might do in an .htaccess file — such as redirect URLs or block IP addresses — can be done from inside the application.

Often, this works in conjunction with the .htaccess file, with the application programatically adding directives.

When this is available, it is usually best to accomplish these tasks from inside the application, rather then editing the .htaccess file yourself. You are less likely to introduce bugs and incompatible directives if you use a well-tested, open-source plugin.


Messing around with your .htaccess file can be great — but it can also cause your server to seize up and start delivering 500 Internal Server Error messages.

Here’s a few ideas to help you through that.

Do One Thing At a Time

This should go without saying, but — sadly — it’s a lesson many of us have to learn over and over again.

Do one thing. Then test it. Then do another thing. Test that.

If you do several things all at once, and then something fails, you won’t know which directive is causing the problem.

Backup Your File Before Each Action

Along with doing only one thing at a time, you should save your file between each thing you are trying. Your saved archive needs to be restorable. This isn’t Microsoft Word where you can just Undo — you need a saved copy of your file.

You should always have the latest working version available in case you mess something up. Always, always, always have the ability to restore to a working version.

This is easiest if you some kind of source management system like git. You can commit after each change, and roll back if you run into any problems.

Check the Error Logs

If you do run into a problem, and you’re having a hard time figuring out why, check your Apache error logs. These often provide valuable information about where to look.

Use Developer Forums to Get Help

Developer forums and Q&A sites like StackOverflow are invaluable tools for even the most seasoned developers and sysadmins. And don’t forget Google. Often, the difference between a bad web master and great one isn’t knowing the answer, its knowing where to find the answer.

Common .htaccess Problems

Sometimes you made a typo. Sometimes you have an esoteric and confusing problem caused by a confluence of unpredictable factors.

Most problems, and the really frustrating ones, are the ones in the middle — the simple, everyday problems that are easy to fix if you just knew about them.

Here’s a few of those.

Bad Filename

There is only one way to spell .htaccess — it has to begin with the dot, and it must be in all lowercase letters.

It seems dumb, but if your .htaccess file isn’t doing what you expect, that should be the first thing you check.

.htaccess Disabled or Partly Disabled

Some shared hosting providers disable .htaccess altogether. Others allow it, but restrict certain directives from being used — they’re just ignored if included.

Similarly, even on VPS plans or your own dedicated servers, .htaccess might be disabled.

If you have access to the httpd.conf file, or other server settings, you can check this yourself. If you find the directive AllowOverride None, you found the culprit. Replace it with AllowOverride All.

If you don’t have access to your httpd.conf file (because you’re on shared hosting, for example), you may need to contact your hosting company’s tech support and see if they can enable it for you, or offer you suggestions on how to accomplish what you’re trying to do in a different way.

Conflicting or Overridden Directives

If you have multiple nested directories, it’s possible for each one to have its own .htaccess file. Every .htaccess file from the root, through each nested directory, applies — they are read in order, descending down the directory tree.

If you set something in your root directory, and then something in subdirectory overrides it, the directive in the .htaccess file closest to the requested file will take precedence.

Also see the mod-rewrite cheat sheet!

.htaccess Frequently Asked Questions

What is .htaccess file in SEO?

The .htaccess file can be used to execute SEO-related tasks like redirects. Redirects can be used to avoid 404 error messages and to let search engine crawlers know which pages they should index. You can also set HTTP headers to improve page load speeds, which may boost your search engine ranking.

In addition, you can use .htaccess to enact a consistent trailing slash policy. This, combined with www and HTTPS rules, can help you avoid duplicate content, which can be penalized by Google.

How do I create a .htaccess file in WordPress?

To create an .htaccess file in WordPress, use this code:

# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress

Note that when you install WordPress, the .htaccess file is automatically created. However, a faulty plugin can corrupt an .htaccess file, resulting in a need to re-create the file.

Why can’t I see my .htaccess file?

If you can’t see your .htaccess file it’s because it doesn’t exist or it’s hidden. To force your FTP client to show these files, you’ll need to change your client settings (i.e., in FileZilla, go to Server > Force showing hidden files). If you’ve made this change and you still don’t see .htaccess, you will need to re-create it.

How many .htaccess files should I have?

Most websites do not need more than one .htaccess file. That’s because the .htaccess files allows you to make server configuration changes on a per-directory basis. However, when hosting multiples sites or complex applications some webmasters may use more than one file per site in order to execute advanced functions.

Where is .htaccess in the cPanel?

To see the .htaccess file, log in to your cPanel account. Then go to Files > File Manager. When asked to choose the directory, select Web Root and make sure that Show Hidden Files is checked. You should now be able to view your .htaccess file in cPanel.

What is the use of .htaccess file in CodeIgniter?

The .htaccess file can be used in conjunction with CodeIgniter to create search engine friendly URLs. By default, CodeIgniter URLs include the index.php file. By using .htaccess you can delete that default index.php file so that it doesn’t appear in all of your application’s URLs.

How useful was this article?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Leave a Comment