Perfect WordPress .htaccess for short loading times
My perfect WordPress .htaccess to make your website load faster too. The speed of a website is not only important for the visitor, but also Google demands a fast page load. With browser caching and gzip compression, we can ensure in the .htaccess that the blog loads noticeably faster. Applicable for WordPress and for any other website.
The .htaccess file is a general configuration file for the Apache web server. WordPress uses the .htaccess for the permalinks to turn unreadable URLs into meaningful addresses. The WordPress .htaccess does this job for you automatically.
If you had a non-optimized .htaccess file or no .htaccess file at all until now, the following guide is guaranteed to make your website faster. Promise!
Back in April 2010, Google had officially announced that site speed will be included as a factor in Google’s ranking.
So site speed is a ranking factor!
Best WordPress Hosting
Hosting recommendations are usually garbage.
Often extremely cheap hosting packages for $ 3 are recommended, others advertise a $ 100 VPS, because they earn the most as an affiliate thereby. In the end, we all just want the fastest possible web space for as little money as possible.
And optimized for WordPress!
What else is important? The server should be a fast backbone for your website and the support should answer as fast as possible, and preferably in your language.
You can get all this at Cloudways from $ 10,00 / month.
I can still remember it well. At that time, load times were not taken that seriously by many webmasters. In 2000, there was no stinginess with Javascript and Flash. The website designs were fulminant and bloated. The opposite of the current flat design boom.
What is the .htaccess?
The file called .htaccess is not strictly necessary to run a website.
Strangely, the name with a dot in front of it may seem to you. On operating systems like Linux and Unix, on which most web servers run, it just means that this file is invisible. There is nothing more behind this dot in front of a file name.
The settings in it also apply to all documents below it. So, you don’t have to copy the file into every subdirectory. With WordPress, the file is included because it is necessary for the so-called permalinks. Thereby, the unattractive URLs are converted into readable addresses.
I maintain a template of my perfect .htaccess file for years, which I use for all my websites. I constantly optimize my .htaccess template and test new features. I then apply improvements to all my other sites.
Where can I find the WordPress .htaccess?
This file is located in the document root of your website. So where the index.html or index.php is located.
With WordPress, you can recognize the root directory by the folders wp-admin
, wp-content
and wp-includes
. In your FTP program you will find the htaccess file just below.
Usually, only one .htaccess is used, which also affects all underlying directories and files.
The default WordPress .htaccess file
WordPress automatically creates a default .htaccess file for each new installation. If the file does not exist, you can recreate it in the Settings > Permalinks menu by clicking the Save Changes button.
The content of the default WordPress .htaccess file:
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
That’s all WordPress writes to this configuration file. If you have other directives, they come from a plugin.
The right file permissions
To protect your .htaccess file from unauthorized access, it should have the correct file permissions.
On Unix and Linux systems, permissions are specified by a three-digit number. Make sure that the permission 644 is assigned.
You can do this in your FTP program like Filezilla by right-clicking the file and selecting File Fixups….
For the owner select Read and Write and for the group and public permissions select Read only.
Be careful with changes
Be careful with changes. If just one letter is in the wrong place, your whole website may stop loading.
Therefore, always make a WordPress backup before you touch the .htaccess. I use the service BlogVault for this.
You should insert your changes before the original WordPress directives. You can recognize them because they are between the comments BEGIN WordPress
and END WordPress
.
Lines that start with a # sign are comments that do not affect the function.
Adjust and extend the .htaccess
For speed, caching and gzip compression are the most important measures in the .htaccess. However, many other things can be regulated in it.
You can open the file with any editor. I use Notepad++ or VS Code and the FTP client FileZilla.
The standard .htaccess of WordPress looks like this:
We leave the existing rules at the very end of the file. Everything new we add in front of it.
1. Enable browser caching
The following rules tell the browser how long certain elements should be stored locally and also be reloaded from there. The local .htaccess
browser caching.
I know, there are templates for this in the net, which are three times as long. But more does not always help more. Endless instructions only make the .htaccess unwieldy and confusing.
I have collected and tested the settings over years. With this, you get the best result.
# Browser Caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access 5 seconds"
ExpiresByType image/jpg "access 1 month"
ExpiresByType image/jpeg "access 1 month"
ExpiresByType image/gif "access 1 month"
ExpiresByType image/png "access 1 month"
ExpiresByType image/ico "access 1 month"
ExpiresByType image/x-icon "access 1 month"
ExpiresByType text/css "access plus 1 day"
ExpiresByType text/javascript "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
</IfModule>
# Alternative Caching
<IfModule mod_headers.c>
Header append Cache-Control "public"
Header append Vary Accept-Encoding
Header set Connection keep-alive
Header unset ETag
FileETag None
</IfModule>
2. gzip compression of traffic
gzip is an open compression standard similar to ZIP. The website is compressed with it before downloading and decompressed again in the browser. This can save up to 80 percent of data traffic. Of course, this also reduces the loading time enormously.
On websiteplanet.com you can check if gzip is active.
With Cloudflare even Brotli compression is active, which is even more efficient.
# gzip compression
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
</IfModule>
3. Protect important WordPress files
After WordPress installation, important files should not be accessible from the outside. For example, this is wp-config.php
, where your MySQL credentials are located.
# No access to install.php
<files install.php>
Order allow,deny
Deny from all
</files>
# No access to wp-config.php
<files wp-config.php>
Order allow,deny
Deny from all
</files>
# No access to .htaccess and .htpasswd
<FilesMatch "(\.htaccess|\.htpasswd)">
Order deny,allow
Deny from all
</FilesMatch>
4. Prevent image hotlinking – image theft
Image hotlinking is when your image from your server is displayed on another website. This can put significant performance demands on your server. This will affect the speed of your website.
You can prevent hotlinking, but keep in mind that if you do, your images will not be able to be displayed on social media such as Facebook and Instagram.
Lines 5 – 7 are exceptions from which images may be retrieved. “yourdomain.com
” you need to replace twice in the code with your actual domain.
# Prevent image hotlinking
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?deinedomain.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?google.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?facebook.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?instagram.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|svg)$ https://deinedomain.com/hotlink-image.jpg [NC,R,L]
5. Redirects and 301 redirects
Since encryption of traffic using SSL has become the standard, you should always redirect http to https.
The ultimate 301 redirect from http to https:
# redirect http to https
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
301 redirects if you changed the address of a page or post:
# 301 redirects
Redirect 301 /old-page/ http://yourdomain.com/new-page/
6. Protect directories
You can protect directories with a username and password. For this you have to put the configuration in the .htaccess file and the username and the encrypted password in the .htpasswd file.
For this, you should have a look at the detailed instructions and the .htpasswd generator.
# Protect directory
AuthUserFile /path/to/.htpasswd
AuthName "Password protected!"
AuthType Basic
Require valid-user
7. Exclude certain IPs and spammers
Unfortunately, it happens again and again that spam from a certain IP hits your website. Replace the X with the IP you want to block.
# Exclude specific IPs
<Limit GET POST>
order allow,deny
deny from XXX.XXX.XXX.XXX
deny from XXX.XXX.XXX.XXX
allow from all
</Limit>
8. block wp-admin for foreign IPs
If you get a static IP address from your internet provider, you can lock the wp-admin directory for everyone and only allow it for your IPs.
For this you have to create a new .htaccess file in the wp-admin directory and insert the following code. Replace the X with your IP.
# enable wp-admin directory for specific IPs only
order deny,allow
deny from all
allow from XX.XXX.XXX.XXX
9. Protect usernames
A brute force attack on your WP admin promises to be successful only if the username is known.
For example, with WordPress, the first user created is usually an admin. You can find out which is the first user by appending “/?author=1” to the domain. You can prevent this with the following lines:
# Prevents the simple reading of usernames
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} .*author=(.+.?) [NC]
RewriteRule (.*) /blog/?author= [NC,L,R=301]
The perfect WordPress .htaccess
But now we come to my optimal WordPress .htaccess file that I use on all my blogs.
Many of the directives shown above are special cases that you can use if needed. I have left these out as they can also cause problems.
Copy and paste the following code into your .htaccess:
# Redirect http to https
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# Browser Caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access 5 seconds"
ExpiresByType image/jpg "access 1 month"
ExpiresByType image/jpeg "access 1 month"
ExpiresByType image/gif "access 1 month"
ExpiresByType image/png "access 1 month"
ExpiresByType image/ico "access 1 month"
ExpiresByType image/x-icon "access 1 month"
ExpiresByType text/css "access plus 1 day"
ExpiresByType text/javascript "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
</IfModule>
# Alternative Caching
<IfModule mod_headers.c>
Header append Cache-Control "public"
Header append Vary Accept-Encoding
Header set Connection keep-alive
Header unset ETag
FileETag None
</IfModule>
# gzip compression
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
</IfModule>
# No access to install.php
<files install.php>
Order allow,deny
Deny from all
</files>
# No access to wp-config.php
<files wp-config.php>
Order allow,deny
Deny from all
</files>
# No access to .htaccess and .htpasswd
<FilesMatch "(\.htaccess|\.htpasswd)">
Order deny,allow
Deny from all
</FilesMatch>
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
How can I test the speed?
Before we start making changes, we must first check the current state of our site so that we have a comparison afterwards. This is the only way to evaluate the changes.
I prefer to use https://gtmetrix.com/ for this purpose.
Other alternatives are:
After testing your site, know your current PageSpeed value, YSlow value, load time, download size and how many requests (loaded files like CSS and JS) were needed when loading your pages.
Compare the values with and without my optimal Apache configuration.
Nginx webserver and .htaccess
If your hoster uses a Nginx web server, you won’t be able to use all the configurations given here because Nginx doesn’t use .htaccess.
Nginx also has its configuration file where you can make similar settings.
Recommendation: My comparison – Nginx vs Apache
Final words
If this is too technical for you, the WordPress plugin WP Rocket might be just what you need.
The caching plugin also does the configuration of the .htaccess for you.
If you had a standard .htaccess or none before, you will see significant improvements in all values.
As you can see, a lot can be achieved with just a few interventions.
Your visitors will thank you with more page views and the search engines with better rankings.
Really good, use that: hotlinking to my blog:) Love from sweden:)
by way not the best htaccess but thanks :)
i really appreciate this htaccess file, it’s powerful for my wordpress