Skip to content

.htaccess tips for WordPress

.htaccess tips for WordPress

The .htaccess file is a powerful tool for your WordPress site. With this configuration file you control your Apache webserver. You can set up redirects, optimize caching and secure your site.

In this guide you'll find practical .htaccess tips specifically for WordPress. From basic configuration to advanced security rules.

What does .htaccess do?

The .htaccess file configures your Apache webserver at directory level. It's located in the root folder of your WordPress installation. The name starts with a dot making it hidden on many systems.

Note: .htaccess only works on Apache servers. Nginx uses different configuration files. Check with your hosting provider which webserver you use.

Capabilities of .htaccess:

  • URL redirects and rewrites
  • Set caching headers
  • Activate compression
  • Block access
  • Set error pages
  • Performance optimizations

A wrong .htaccess can make your entire site inaccessible. Always make a backup before making changes.

Default WordPress .htaccess

WordPress automatically generates a basic .htaccess during installation. This file provides permalink functionality.

Default WordPress .htaccess:

# 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

These rules make pretty permalinks work. WordPress writes this automatically when you set permalinks in admin.

Important: add custom rules above or below the WordPress section. Don't manually edit rules between BEGIN and END WordPress as WordPress can overwrite them.

Set up redirects with .htaccess

Redirects send your visitors from old to new URLs. This is important for SEO and user experience.

301 redirect (permanent):

Redirect 301 /old-page https://example.com/new-page

From non-www to www:

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

From www to non-www:

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

Force HTTP to HTTPS:

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

Caching headers for better performance

Browser caching lets visitors store files locally. This significantly speeds up your site for returning visitors.

Leverage browser caching:

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "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/pdf "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
</IfModule>

These rules tell browsers how long they can cache files. Images 1 year, CSS and JS 1 month.

Cache-Control headers:

<IfModule mod_headers.c>
<FilesMatch "\.(jpg|jpeg|png|gif|svg|css|js)$">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
</IfModule>

Activate GZIP compression

GZIP compression reduces files before they're sent to the browser. This saves bandwidth and speeds up load times.

Basic GZIP compression:

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE text/plain
</IfModule>

Extended GZIP configuration:

<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
<IfModule mod_setenvif.c>
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>
<IfModule mod_headers.c>
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>

Test compression on tools like GTmetrix or Google PageSpeed Insights.

Security rules for WordPress

With .htaccess you can better secure your WordPress site against attacks.

Protect wp-config.php:

<Files wp-config.php>
order allow,deny
deny from all
</Files>

Disable XML-RPC: XML-RPC is often abused for brute force attacks:

<Files xmlrpc.php>
order deny,allow
deny from all
</Files>

Disable directory browsing:

Options -Indexes

Restrict wp-admin access to IP:

<Files wp-login.php>
order deny,allow
deny from all
allow from 123.123.123.123
</Files>

Replace 123.123.123.123 with your own IP address.

Prevent file injection:

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]

Block hotlinking

Hotlinking is when other sites link directly to your images. This steals your bandwidth.

Block image hotlinking:

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

Replace example.com with your own domain.

With placeholder image:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ https://example.com/hotlink.jpg [R,L]

Now hotlinkers see a placeholder instead of your real image.

Protect upload directory

The wp-content/uploads directory should not execute PHP files. This prevents hackers from uploading malware via forms.

Block PHP execution in uploads:

<Directory "/var/www/html/wp-content/uploads/">
<Files "*.php">
Order Deny,Allow
Deny from All
</Files>
</Directory>

Or with .htaccess in the uploads folder itself:

<Files *.php>
deny from all
</Files>

Custom error pages

With .htaccess you can set custom error pages for 404, 500 and other errors.

Set error pages:

ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
ErrorDocument 500 /500.html

Or to WordPress pages:

ErrorDocument 404 /index.php?error=404

Make sure your custom error pages exist before activating these.

Performance optimizations

Disable ETags: ETags can cause caching issues with load balanced hosting:

<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag None

Optimize KeepAlive:

<IfModule mod_headers.c>
Header set Connection keep-alive
</IfModule>

Force lazy loading:

<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
</IfModule>

Common errors and solutions

500 Internal Server Error: This often comes from syntax errors in .htaccess. Check your Apache error logs:

tail -f /var/log/apache2/error.log

Or via hosting control panel. Remove recently added rules and test again.

Redirects don't work: Check if mod_rewrite is active. Some shared hosting has this off by default. Ask your provider to activate it.

Site doesn't load after .htaccess change: Rename .htaccess to .htaccess_old via FTP. If your site works now, the error was in .htaccess.

Permanent redirect loop: Check if you don't have multiple conflicting redirects. Test with browser incognito mode.

Test and debug .htaccess

Syntax checker online: Use tools like htaccess tester to validate syntax before upload.

Check server configuration: Some hosting providers have limitations on .htaccess. Check with phpinfo() which modules are active.

Test redirects: Use redirect checker tools to verify redirects work correctly and don't cause loops.

Nginx alternatives

If your server uses Nginx, .htaccess doesn't work. Configuration goes via nginx.conf or server blocks.

Nginx redirect example:

location /old-page {
    return 301 https://example.com/new-page;
}

Many managed WordPress hosting providers use Nginx. Check your hosting documentation for configuration options.

Best practices for .htaccess

Always make a backup: before modifying .htaccess download a backup. One mistake can break your site.

Test on staging: test changes first on a staging environment. Then on production.

Add comments: use # for comments. This helps later with maintenance.

Keep minimal: only add rules you really need. More rules is more overhead.

Monitor performance: check after changes if your site loads faster. Use tools like GTmetrix.

Security first: start with security rules before optimizing performance.

Complete .htaccess example

Here's a complete .htaccess with all important optimizations:

# Security
Options -Indexes
<Files wp-config.php>
order allow,deny
deny from all
</Files>

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

# GZIP compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
</IfModule>

# Browser caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresDefault "access plus 2 days"
</IfModule>

# WordPress 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

By configuring your .htaccess properly you make your WordPress site faster and more secure. Choose the rules that fit your situation. Always test first before applying changes to production.

Frequently Asked Questions

Is WordPress free?

WordPress itself is free open-source software. You only pay for hosting, a domain name, and any premium themes or plugins you want to use.

How difficult is WordPress to learn?

WordPress is relatively easy to learn. You can master the basic functions within a few hours. Advanced customizations require more time.

Can I move WordPress to a different host later?

Yes, WordPress websites can be moved to a different hosting provider. Most providers offer free assistance for this.

Was this article helpful?

Compare hosting packages directly to find the best choice for your situation.