
The .htaccess file is one of the most powerful configuration files on an Apache web server. For WordPress sites, it handles URL rewrites, security restrictions, performance optimizations, and access control. A well-tuned .htaccess can significantly improve both security and page load speed with no plugin required.
Always back up your .htaccess before making changes. A syntax error can make your entire site return a 500 Internal Server Error. Keep a copy of the working file so you can restore it quickly.
1. Standard WordPress .htaccess (Default)
WordPress generates this basic .htaccess automatically. Never remove it — it's required for pretty permalinks:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Add all custom rules outside the # BEGIN WordPress / # END WordPress block so updates don't overwrite them.
2. Force HTTPS (HTTP → HTTPS Redirect)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
3. Protect Sensitive Files
Protect wp-config.php
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>
Protect .htaccess Itself
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
Block XML-RPC
<Files xmlrpc.php>
Order Allow,Deny
Deny from all
</Files>
Disable Directory Browsing
Options -Indexes
4. Add Security Headers
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>
5. Hotlink Protection
Prevent other sites from embedding your images directly (stealing bandwidth):
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\.)?yourdomain\.com/ [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp|svg)$ - [F,NC]
</IfModule>
Replace yourdomain.com with your actual domain.
6. Enable GZIP Compression
GZIP typically reduces HTML, CSS, and JS file sizes by 60–80%, significantly improving page load times:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml
AddOutputFilterByType DEFLATE text/css text/javascript
AddOutputFilterByType DEFLATE application/javascript application/x-javascript
AddOutputFilterByType DEFLATE application/json application/xml
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
7. Browser Caching (Cache-Control Headers)
Tell browsers how long to cache static assets, reducing repeat load times:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/gif "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 application/x-javascript "access plus 1 month"
ExpiresByType text/html "access plus 1 day"
</IfModule>
8. Block Common Bad Bots
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (AhrefsBot|SemrushBot|DotBot|MJ12bot) [NC]
RewriteRule .* - [F,L]
</IfModule>
Note: Blocking SEO crawlers like Ahrefs and Semrush prevents them from including your site in their index databases, which can reduce the number of inbound link analyses. Only block them if server load is a concern.
8.5. Protect wp-login.php from Brute Force
The WordPress login page is a constant target for brute-force attacks. Restricting it by IP address is the most effective server-level protection:
# Allow only specific IPs to access wp-login.php
<Files wp-login.php>
Order Deny,Allow
Deny from all
Allow from YOUR.IP.HERE
</Files>
Replace YOUR.IP.HERE with your actual IP address. If you have a dynamic IP (changes with each connection), use a plugin such as Limit Login Attempts Reloaded instead, or change the login URL with WPS Hide Login to make it unreachable by bots in the first place.
8.6. Block Malicious Bots and Vulnerability Scanners
Automated bots that probe for vulnerabilities consume server resources and inflate your traffic logs. Block them by User-Agent string:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (masscan|nikto|sqlmap|havij|netsparker|ZmEu) [NC]
RewriteRule .* - [F,L]
</IfModule>
To block a specific IP range that is actively attacking your site:
<RequireAll>
Require all granted
Require not ip 185.220.101.0/24
</RequireAll>
Note: Blocking popular SEO crawlers (Ahrefs, Semrush) prevents them from indexing your backlink profile in their databases. Only block bots that are causing real performance problems — check your access logs first.
8.7. Disable PHP Execution in Upload Directories
A common attack vector involves uploading a PHP file disguised as an image, then executing it through the browser. Prevent this by disabling PHP execution inside the WordPress uploads folder:
# Place this in a new .htaccess inside wp-content/uploads/
<FilesMatch "\.php$">
Order Allow,Deny
Deny from all
</FilesMatch>
Create a separate .htaccess file with this rule and place it inside your wp-content/uploads/ directory. Even if a PHP file is uploaded, it cannot be executed — it will return a 403 Forbidden error instead.
Strongly recommended: This single rule eliminates an entire category of WordPress shell upload attacks. It takes less than 30 seconds to implement and requires no plugin.
9. Custom Error Pages
ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
ErrorDocument 500 /500.html
10. How to Test That Your .htaccess Rules Are Working
After adding any new rule, test it immediately rather than waiting to notice a problem. Here is how to verify each common rule type:
Test HTTPS redirect
Type http:// (without the "s") before your domain in the browser address bar. The URL should immediately change to https://. Alternatively, run curl -I http://yourdomain.com — a 301 status code confirms the redirect is working.
Test directory browsing protection
Navigate to a folder on your site that has no index file, for example https://yourdomain.com/wp-content/. With Options -Indexes in effect, you should see a 403 Forbidden error instead of a file listing.
Test security headers
Visit securityheaders.com, enter your domain, and click Scan. The report shows which headers are present and gives an overall grade. A well-configured WordPress site with the rules in this guide should receive grade A or A+.
Test GZIP compression
Run your site through GTmetrix or Google PageSpeed Insights. If GZIP is active, you will not see a "Enable text compression" recommendation in the results.
11. Common .htaccess Mistakes and How to Fix Them
Immediate 500 error after saving
A syntax error causes Apache to reject the entire file. Restore your backup immediately, then review the new rule line by line. Common causes: missing closing </IfModule>, incorrect spacing, or an unrecognized directive.
Redirect loop (ERR_TOO_MANY_REDIRECTS)
This happens when a rewrite rule redirects to itself. For the HTTPS rule, always include RewriteCond %{HTTPS} off so the redirect only fires for HTTP requests, not for HTTPS requests that have already been redirected.
WordPress permalinks stop working
If a custom rule interferes with WordPress routing, go to WordPress Admin → Settings → Permalinks and click Save. WordPress will regenerate the # BEGIN WordPress block with the correct rewrite rules.
Security headers not appearing
Apache must have mod_headers enabled for Header always set directives to work. Most managed hosting providers have it enabled by default. If headers are missing after adding the rules, contact your hosting provider to confirm the module is active.
WordPress Hosting with Apache & DirectAdmin
AsiaGB Hosting runs on Apache with full .htaccess support. Manage your site through DirectAdmin — no command line required. Starting at 500 THB/year.
View Hosting Plans →