.htaccess snippets

Copy-paste-ready .htaccess code blocks for Apache HTTP Server: redirects, access control, URL rewriting, security headers, and hotlink prevention.

Ready-to-use .htaccess directive blocks for common Apache HTTP Server configuration tasks.

Blocking Access with .htaccess

Block a Single IP Address with .htaccess

The .htaccess Require directive in Apache 2.4 denies access to a specific IP address. Wrap the directive in a <RequireAll> container to allow all traffic except the blocked IP.

<RequireAll>
    Require all granted
    Require not ip 203.0.113.50
</RequireAll>

Block Multiple IP Addresses with .htaccess

The .htaccess file blocks multiple IP addresses by adding each to a separate Require not ip line inside the <RequireAll> container.

<RequireAll>
    Require all granted
    Require not ip 203.0.113.50
    Require not ip 198.51.100.25
</RequireAll>

Block an IP Subnet with .htaccess

The .htaccess Require directive blocks an entire subnet using CIDR notation. Apache denies all IP addresses within the specified range.

<RequireAll>
    Require all granted
    Require not ip 203.0.113.0/24
</RequireAll>

Block a User-Agent with .htaccess

The .htaccess mod_rewrite module blocks requests from a specific user-agent string. Apache returns a 403 Forbidden response when the HTTP_USER_AGENT header matches the pattern.

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "BadBot" [NC]
RewriteRule .* - [F,L]

Denying Access with .htaccess

Deny Access to a Directory with .htaccess

The .htaccess Require directive blocks all access to the directory where the file resides. Place this .htaccess file inside the directory to protect.

Require all denied

Deny Access to a Specific File with .htaccess

The .htaccess <Files> directive restricts access to a specific file by name. Apache returns a 403 Forbidden response for matching requests.

<Files "secret.pdf">
    Require all denied
</Files>

Deny Access to Hidden Files and Directories with .htaccess

The .htaccess mod_rewrite module blocks access to dotfiles and dotfolders (files and directories starting with .). The pattern excludes the .well-known directory, which Let's Encrypt and other ACME clients require.

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\.(?!well-known\/)" - [F]

Preventing Hotlinking with .htaccess

Prevent Image and Asset Hotlinking with .htaccess

The .htaccess mod_rewrite module blocks external sites from embedding static files (images, CSS, JavaScript) directly. Apache checks the HTTP_REFERER header and returns a 403 Forbidden response for requests originating from other domains.

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com/ [NC]
RewriteRule \.(css|js|jpg|jpeg|png|gif|svg|webp|zip|pdf)$ - [F,NC,L]

Replace example\.com with the actual domain. Add or remove file extensions in the RewriteRule pattern as needed.

Redirecting with .htaccess

Force HTTPS with .htaccess

The .htaccess mod_rewrite module redirects all HTTP requests to HTTPS with a 301 permanent redirect. Place this block before other rewrite rules.

RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Force www with .htaccess

The .htaccess mod_rewrite module redirects the bare domain to the www subdomain. Replace example\.com with the actual domain.

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

Force www Except Subdomains with .htaccess

The .htaccess mod_rewrite module adds www to the bare domain without affecting existing subdomains. The RewriteCond pattern matches only single-part hostnames (no subdomain prefix).

RewriteEngine On
RewriteCond %{HTTP_HOST} ^[0-9a-zA-Z-]+\.[a-zA-Z]{2,}$
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Force Non-www with .htaccess

The .htaccess mod_rewrite module redirects www requests to the bare domain. Replace example\.com with the actual domain.

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

Force Trailing Slash with .htaccess

The .htaccess mod_rewrite module appends a trailing slash to URLs that lack one. Apache issues a 301 redirect from /about to /about/.

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

Remove Trailing Slash with .htaccess

The .htaccess mod_rewrite module strips the trailing slash from URLs. Apache issues a 301 redirect from /about/ to /about. The RewriteCond excludes actual directories.

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

Redirect to a New Domain with .htaccess

The .htaccess Redirect directive sends all requests to a new domain while preserving the URL path. A request for olddomain.com/about redirects to newdomain.com/about.

Redirect 301 / https://newdomain.com/

Redirect All URLs to a Single Page with .htaccess

The .htaccess mod_rewrite module redirects every URL on the old domain to the homepage of a new domain. All paths resolve to one destination.

RewriteEngine On
RewriteRule ^(.*)$ https://newdomain.com/ [R=301,L]

Removing File Extensions with .htaccess

Remove .html Extension from URLs with .htaccess

The .htaccess mod_rewrite module serves .html files without the extension in the URL. A request for /about resolves to /about.html on disk.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]

Remove .php Extension from URLs with .htaccess

The .htaccess mod_rewrite module serves .php files without the extension in the URL. Replace .html with .php in the RewriteRule.

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

Rename .php to .html in URLs with .htaccess

The .htaccess mod_rewrite module rewrites .html URLs to serve the corresponding .php file. Visitors see .html in the browser; Apache serves .php on disk.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)\.html$ /$1.php [L]

Security Headers in .htaccess

Remove X-Powered-By Header with .htaccess

The .htaccess mod_headers module removes the X-Powered-By response header. This header discloses the server-side framework and version, which attackers use for reconnaissance.

<IfModule mod_headers.c>
    Header unset X-Powered-By
    Header always unset X-Powered-By
</IfModule>

Set Custom Error Pages with .htaccess

The .htaccess ErrorDocument directive maps HTTP status codes to custom error pages. Apache serves the specified file instead of the default error response.

ErrorDocument 400 /errors/bad-request.html
ErrorDocument 401 /errors/unauthorized.html
ErrorDocument 403 /errors/forbidden.html
ErrorDocument 404 /errors/not-found.html
ErrorDocument 500 /errors/server-error.html