An htaccess generator online produces valid Apache .htaccess configuration without requiring you to memorize mod_rewrite syntax or risk a 500 error from a misplaced bracket. The .htaccess file (short for “hypertext access”) is a per-directory configuration file that Apache reads on every request, letting you control redirects, headers, authentication, and compression without touching the main server config.
What .htaccess Does and When to Use It
.htaccess only works on Apache servers with AllowOverride enabled. If you are on Nginx, LiteSpeed, or a CDN-only setup, these rules do not apply — Nginx has no equivalent per-directory config file; its rules go in server {} blocks.
When .htaccess is the right tool:
- Shared hosting where you cannot edit
httpd.conf - WordPress, Joomla, or Drupal sites (all use
.htaccessfor pretty URLs) - Rapid rule deployment without a server restart
When to prefer the main server config or Nginx:
- High-traffic sites (
.htaccessis re-read on every request, adding latency) - Container or serverless environments
- Rules that need to apply globally across vhosts
Essential .htaccess Rules
Force HTTPS (HTTP to HTTPS redirect)
The most common .htaccess rule — redirect all HTTP traffic to HTTPS. This is also a Google ranking signal.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you are behind a load balancer that terminates SSL, use the forwarded header instead:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
WWW to non-WWW (or reverse)
Pick one canonical form and redirect the other:
# Non-WWW canonical
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# WWW canonical
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
301 Permanent Redirect
Move a specific page to a new URL:
Redirect 301 /old-page https://yourdomain.com/new-page
For a pattern-based redirect using regex:
RewriteEngine On
RewriteRule ^blog/(.+)$ /articles/$1 [R=301,L]
Custom 404 Error Page
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
ErrorDocument 403 /403.html
CORS Headers
Allow cross-origin requests for a specific domain or all origins:
# Allow specific origin
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://app.yourdomain.com"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
</IfModule>
# Allow all origins (public API or font serving)
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Basic Authentication (Password Protection)
Protect a directory with a username and password:
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
Require valid-user
Generate the .htpasswd file:
htpasswd -c /path/to/.htpasswd username
# You will be prompted for a password
To protect a single file instead of the whole directory:
<Files "admin.php">
AuthType Basic
AuthName "Admin"
AuthUserFile /path/to/.htpasswd
Require valid-user
</Files>
Gzip Compression
Compress text-based responses to reduce transfer size — typically 60-80% for HTML, CSS, and JavaScript:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE application/xml image/svg+xml
AddOutputFilterByType DEFLATE font/woff2 font/woff
</IfModule>
Browser Cache Headers
Tell browsers how long to cache static assets:
<IfModule mod_expires.c>
ExpiresActive On
# Images
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# Fonts
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
# HTML — don't cache long
ExpiresByType text/html "access plus 0 seconds"
</IfModule>
If you use content hashing in filenames (as Vite, webpack, and Next.js do), use immutable for maximum cache efficiency:
<FilesMatch "\.[0-9a-f]{8,}\.(js|css|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
Block Hotlinking
Prevent other sites from embedding your images and consuming your bandwidth:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com/ [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp|svg)$ - [F,L]
Security Headers
<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 filter in older browsers
Header always set X-XSS-Protection "1; mode=block"
# Referrer policy
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Remove server signature
Header always unset X-Powered-By
Header always unset Server
</IfModule>
Testing Your .htaccess Rules
curl — verify redirects
# Follow redirects and show final URL
curl -L -I https://yourdomain.com/old-page
# See all redirect hops
curl -v https://yourdomain.com/old-page 2>&1 | grep -E "< HTTP|Location:"
Test CORS headers
curl -H "Origin: https://other.com" \
-H "Access-Control-Request-Method: GET" \
-I https://yourdomain.com/api/resource
Test gzip
curl -H "Accept-Encoding: gzip" -I https://yourdomain.com/
# Look for: Content-Encoding: gzip
Check cache headers
curl -I https://yourdomain.com/static/app.js
# Look for: Cache-Control and Expires headers
Common Mistakes
1. Missing RewriteEngine On — Every block using RewriteRule needs this line first. Forgetting it produces a 500 error.
2. Rule order matters — Apache processes rules top to bottom and stops at the first match with [L]. Put more specific rules before broad ones.
3. Infinite redirect loops — If your HTTPS redirect runs even when already on HTTPS, you get a redirect loop. Always check %{HTTPS} off or %{HTTP:X-Forwarded-Proto} !https.
4. Path to .htpasswd — Use an absolute server path, not a relative URL. Relative paths break on most setups.
5. mod_rewrite not enabled — On Ubuntu/Debian, run sudo a2enmod rewrite && sudo systemctl restart apache2.
Build Your .htaccess Without Guesswork
The rules above cover 90% of real-world use cases, but combining them correctly — especially when mixing redirects, authentication, and cache rules — requires careful ordering and syntax.
Select the rules you need, fill in your domain and paths, and get a production-ready .htaccess file with correct ordering, no syntax errors, and comments explaining each block.