.htaccess CheatSheet

All the important Apache .htaccess web server rules and config options


(Note: It is assumed that you have `mod_rewrite` installed and enabled. The first line should be ‘RewriteEngine on’ to enable this)

Serve All Requests With One PHP File

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*)$ /index.php [NC,L,QSA] 

Force www with .htaccess

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

Force www in a Generic Way with .htaccess

RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

Force non-www with .htaccess

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

Force non-www in a Generic Way with .htaccess

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.
RewriteCond %{HTTPS}s ^on(s)|off
RewriteCond http%1://%{HTTP_HOST} ^(https?://)(www\.)?(.+)$
RewriteRule ^ %1%3%{REQUEST_URI} [R=301,L] 

Force HTTPS with .htaccess

RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 

Force HTTPS Behind a Proxy with .htaccess

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} 

Force Trailing Slash with .htaccess

RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L] 

Remove Trailing Slash with .htaccess

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L] 

Redirect a Single Page with .htaccess

Redirect 301 /oldpage.html https://www.yoursite.com/newpage.html
Redirect 301 /oldpage2.html https://www.yoursite.com/folder/ 

Alias a Single Directory with .htaccess

RewriteEngine On
RewriteRule ^source-directory/(.*) target-directory/$1 

Alias Paths To Script with .htaccess

RewriteEngine On
RewriteRule ^$ index.fcgi/ [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L] 

Redirect an Entire Site with .htaccess

Redirect 301 / https://newsite.com/

Alias “Clean” URLs with .htaccess

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^.]+)$ $1.php [NC,L] 

Deny All Access with .htaccess

# Require all denied 

Only allow certain IPs with .htaccess

# Require all denied
# Require ip xxx.xxx.xxx.xxx 

Block IP Address with .htaccesss

# Require all granted
# Require not ip xxx.xxx.xxx.xxx
# Require not ip xxx.xxx.xxx.xxy 

Allow access only from LAN with .htaccess

order deny,allow
deny from all
allow from 

Deny Access To Certain User Agents with .htaccess

RewriteCond %{HTTP_USER_AGENT} ^User\ Agent\ 1 [OR]
RewriteCond %{HTTP_USER_AGENT} ^Another\ Bot\ You\ Want\ To\ Block [OR]
RewriteCond %{HTTP_USER_AGENT} ^Another\ UA
RewriteRule ^.* - [F,L] 

Deny Access to Hidden Files and Directories with .htaccess

<files your-file-name.txt>
order allow,deny
deny from all

Deny Access to Backup and Source Files with .htaccess

<FilesMatch "(\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|swp)|~)$">
    ## Apache 2.2
    Order allow,deny
    Deny from all
    Satisfy All

    ## Apache 2.4
    # Require all denied

Disable Directory Browsing with .htaccess

Options All -Indexes 

Enable Directory Listings with .htaccess

Options All +Indexes 

Disable Listing Of Certain Filetypes with .htaccess

IndexIgnore *.zip *.mp4 *.pdf 

Disable Image Hotlinking with .htaccess

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L] 

Redirect hotlinkers and show a different image with .htaccess

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\.)?your-website.com/.*$ [NC]
RewriteRule \.(gif|jpg|png)$ https://www.your-website.com/do-not-hotlink-our-content.jpg [R,L] 

Deny Access from certain referrers with .htaccess

RewriteCond %{HTTP_REFERER} block-this-referer\.com [NC,OR]
RewriteCond %{HTTP_REFERER} and-block-traffic-that-this-site-sends\.com [NC]
RewriteRule .* - [F] 

Password Protect a Directory with .htaccess

AuthType Basic
AuthName "Password Protected Dir Title"
AuthUserFile /home/hidden/directory/here/.htpasswd
Require valid-user 

Password Protect a File or Several Files with .htaccess

AuthName "Password Protected Directory Title"
AuthType Basic
AuthUserFile /home/hidden/directory/here/.htpasswd

<Files "/a-private-file.txt">
Require valid-user

<FilesMatch ^((one|two|three)-rings?\.o)$>
Require valid-user

Compress Text Files (gzip/deflate output) with .htaccess

<IfModule mod_deflate.c>

        # Force compression for mangled headers.
        # https://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping
        <IfModule mod_setenvif.c>
                <IfModule mod_headers.c>
                        SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
                        RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding

        # Compress all output labeled with one of the following MIME-types
        # (for Apache versions below 2.3.7, you don't need to enable `mod_filter`
        #    and can remove the `<IfModule mod_filter.c>` and `</IfModule>` lines
        #    as `AddOutputFilterByType` is still in the core directives).
        <IfModule mod_filter.c>
            AddOutputFilterByType DEFLATE application/atom+xml \
              application/javascript \
              application/json \
              application/rss+xml \
              application/vnd.ms-fontobject \
              application/x-font-ttf \
              application/x-web-app-manifest+json \
              application/xhtml+xml \
              application/xml \
              font/opentype \
              image/svg+xml \
              image/x-icon \
              text/css \
              text/html \
              text/plain \
              text/x-component \


Turn eTags Off with .htaccess

<IfModule mod_headers.c>
        Header unset ETag
FileETag None 

Limit Upload File Size with .htaccess

LimitRequestBody 1048576 

Server Variables for mod_re足write with .htaccess


Set PHP Variables with .htaccess

php_value <key> <val> 

Custom Error Pages with .htaccess

ErrorDocument 500 "Houston, we have a problem."
ErrorDocument 401 https://error.yourdomain.com/mordor.html
ErrorDocument 404 /errors/halflife3.html 

Redirect users to a maintenance page in .htaccess

ErrorDocument 403 YourMaintenancePageFilenameOrFullUrlUrl.html
Order deny,allow
Deny from all
Allow from 555.555.555.555 

Force Downloading with .htaccess

<Files *.md>
        ForceType application/octet-stream
        Header set Content-Disposition attachment

Disable Showing Server Info with .htaccess

ServerSignature Off 

Prevent Downloading with .htaccess

<FilesMatch "\.(tex|log|aux)$">
        Header set Content-Type text/plain

Allow Cross-Domain Fonts with .htaccess

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

Auto UTF-8 Encode with .htaccess

# Use UTF-8 encoding for anything served text/plain or text/html
AddDefaultCharset utf-8

# Force UTF-8 for a number of file formats
AddCharset utf-8 .atom .css .js .json .rss .vtt .xml 

Set Server Timezone with .htaccess

SetEnv TZ America/Los_Angeles 

Switch to Another PHP Version with .htaccess

AddHandler application/x-httpd-php55 .php 

Execute PHP with a different file extension with .htaccess

AddType application/x-httpd-php .ext 

Serve WebP Images Automatically from .htaccess

RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1] 

Add canonical links to all the PDF files in a folder

RewriteRule ([^/]+)\.pdf$ - [E=FILENAME:%{HTTP_HOST}%{REQUEST_URI}]
<FilesMatch "\.pdf$">
    Header add Link '<https://%{FILENAME}e>; rel="canonical"'