The Shack Web Development The .htaccess Cheatsheet

The .htaccess Cheatsheet: Redirects, Security Headers, and More

Back to All Posts

If your site runs on Apache — which includes most shared hosting, cPanel environments, and many VPS setups — the .htaccess file is your primary tool for controlling redirects, security headers, access restrictions, URL rewrites, and custom error pages without touching server configuration files. The DevToolShack .htaccess Generator builds common configurations from a form — no Apache expertise required.

Test before deploying. An invalid .htaccess file returns a 500 Internal Server Error for all requests. Always test in a staging environment, and keep a working backup before making changes.

Redirects

Simple 301 Redirect (Permanent)

# Redirect a single page
Redirect 301 /old-page.html https://example.com/new-page

# Redirect an old directory to a new one
Redirect 301 /old-blog/ https://example.com/blog/

www to non-www (or vice versa)

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

# Redirect non-www to www
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

Force HTTPS

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

Remove Trailing Slash

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

Security Headers

Security headers instruct browsers how to handle your content. These are some of the most impactful headers you can add:

<IfModule mod_headers.c>
  # Prevent clickjacking
  Header always set X-Frame-Options "SAMEORIGIN"

  # Prevent MIME type sniffing
  Header always set X-Content-Type-Options "nosniff"

  # Enable XSS protection in older browsers
  Header always set X-XSS-Protection "1; mode=block"

  # Force HTTPS for 1 year (HSTS)
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

  # Control referrer information
  Header always set Referrer-Policy "strict-origin-when-cross-origin"

  # Limit browser features (Permissions Policy)
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>

Custom Error Pages

# Custom error pages
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
ErrorDocument 403 /403.html

URL Rewriting

Clean URLs — hiding .php extensions and query strings behind readable paths:

RewriteEngine On

# Remove .php extension from URLs
# /about.php becomes /about
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

# WordPress pretty permalinks
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Access Control

# Block all access to a directory
<Directory /var/www/html/private>
  Require all denied
</Directory>

# Block access by IP
<RequireAll>
  Require all granted
  Require not ip 192.168.1.100
</RequireAll>

# Password protect a directory
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
Require valid-user

# Block access to sensitive files
<FilesMatch "^(\.htaccess|\.htpasswd|wp-config\.php)$">
  Require all denied
</FilesMatch>

Performance: Caching and Compression

# Enable GZIP compression
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css application/javascript
  AddOutputFilterByType DEFLATE text/xml application/json image/svg+xml
</IfModule>

# Browser caching
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpg  "access plus 1 year"
  ExpiresByType image/png  "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType text/css   "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  ExpiresByType text/html  "access plus 1 day"
</IfModule>

Understanding RewriteRule Flags

FlagMeaning
R=301External redirect with status code 301
LLast rule — stop processing further rules
NCNo case — case-insensitive matching
QSAQuery String Append — preserve the original query string
FForbidden — return 403
GGone — return 410
Generate it, don't memorise it: The htaccess Generator produces common configurations from a form — HTTPS redirect, www/non-www, custom error pages, security headers, and caching rules. Pair it with the Robots.txt Generator for a complete server configuration setup. Always keep a working backup before deploying changes.