.htaccess is one of those scary files that you’re probably too afraid to touch. You’ve probably heard this file spoken about by SEOs, Web Developers and technical know-it-alls in Facebook Groups.
It’s a dotfile, often hidden from commercial hosting control panels without the tick of a box or connecting via (s)FTP. Dotfiles contain configuration information for the server environment and its directory. There are many different types of dotfiles that developers and software engineers use to have more control over their local development environment.
Bloggers and website owners can also make use of this file, as it’s relatively well documented and extremely easy to edit.
Your WordPress site has a htaccess file in the same directory where your core WordPress files are saved. The only use that WordPress has for it is to rewrite permalinks, but there are loads of different plugins that also make changes to your htaccess file for various different functions.
Caching plugins will add caching rules, security plugins will add security rules and redirection plugins take care of (you’ve guessed it) redirections.
.htaccess is not a WordPress file, it’s a standard file that’s part of the Apache configuration, and it’s not always required. Most WordPress websites will be using a .htaccess file, even if you’ve never touched it!
It’s actually one of the most important files on your entire website! This article will outline and explain what you can do with it as a blogger to improve your website to make it more efficient and secure.
Contents
Proceed with caution
This article is intended for advanced users who are familiar with the basics of the WordPress file system, FTP and Web servers.
One syntax error or typo can make your website inaccessible. Don’t worry, htaccess changes are instantaneous so you can always ‘undo’ what you just did, but you need to be sensible when working with such an important file.
You should not edit your htaccess file unless:
- You have access to the website hosting file manager or (s)FTP
- You have a recent backup of your htaccess file
- You’re editing it using a proper text editor (TextEdit, Notepad or your IDE of choice) and not a WordPress plugin*
- You’re sure about which existing plugins are adding rules to .htaccess on your site and what each one does
Also note that the code snippets provided in this article will not work with every host. You must check your own host’s configuration before using any of these snippets and I hold no responsibility if you don’t know what you’re doing!
*Using a plugin to make changes to htaccess is a terrible idea. If you make a mistake and save the file, you’ll have no way to undo that mistake without opening the file directly from the server, even if you have a backup. Yoast SEO has the option to edit the .htaccess file under Tools > File Editor, but you should not use this setting!
1. WordPress Security and Hardening
The first (and arguably most important) thing that .htaccess can be used for within WordPress is for hardening and security. These snippets added to your .htaccess file blocks the following:
- xmlrpc.php requests
- author username scans
- access to the wp-config.php file
XMLRPC is required by certain plugins, including JetPack, Windows Live Writer, the WordPress.com Plugin and possibly many other third-party plugins and services I’m not aware of. Blocking it will obviously stop these tools from working, but XMLRPC is not extremely secure as it allows for direct writing to the WordPress database. It was incredibly useful in 2009, but now, you should disable it in almost all cases. The REST API is much more secure way to connect to WordPress externally, so you can safely block XMLRPC if you’re not using it.
If an attackers fails to get in via your login page, XMLRPC is the next place they’ll look. You’ll also notice a lot fewer content scrapers targeting your site with this disabled – so that’s a win-win!
Blocking author scans and access to the wp-config file also provide an extra layer of security. The wp-config file contains your database credentials, and if an attacker gained access to this file then they instantly have complete control over your site. Protecting it is common sense.
# Block WordPress xmlrpc.php requests
<Files xmlrpc.php>
order deny,allow
deny from all
allow from 123.123.123.123
</Files>
# BEGIN block author scans
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (author=\d+) [NC]
RewriteRule .* - [F]
# END block author scans
# Block external access to wp-config file
<files wp-config.php>
order allow,deny
deny from all
</files>
2. Redirections
If you need to redirect a page on your site because you’ve changed its URL, don’t reach straight for the Redirection plugin.
Redirections are much faster and more efficient if done at the server-level, whereas the Redirection plugin stores redirections within the website’s database, which is much slower and far less efficient.
.htaccess is the first file read during a request, so it makes more sense to redirect any visitors at that point, before the site begins to load.
The popular Redirection plugin does have an option to export your redirections for use in the .htaccess file using the mod_rewrite directive. It will produce something like this:
# 301 Redirect - replace the details below with your URLs
RedirectMatch 301 ^/old-permalink/.*$ https://www.mywebsite.com/new-link
# Or use Mod Rewrite instead
<IfModule mod_rewrite.c>
RewriteRule ^/old-permalink/ /new-permalink [R=301,L]
</IfModule>
3. Browser Caching
Browser caching directives within htaccess tell the visitor’s browser to store certain information within its cache, to make subsequent loads faster. Things like images, CSS, Favicons and other elements of your site that do not change very often (if at all) can be safely cached.
This snippet is a commonly found method to enable browser caching. Many caching plugins will take care of this for you, so there may be no need to add this at all. Check your site’s configuration before adding any caching directives.
# Setup browser caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 2 days"
</IfModule>
4. HTTP Headers
There are currently 7 Security Headers you can enable on your site. Before installing these headers, please prepare your site correctly.
The headers are, very briefly:
- X Content Type Options – “nosniff” is the only value that works here
- XSS Protection – Use this in conjunction with the Content Security Policy
- X-Frame Options – this can prevent content from your site being embedded within an <iframe> on another domain.
- HSTS – Strict Transport Security
- Referrer Policy – how much information is stored by the browser about navigating away from the site
- Permission Policy (formerly called Features Policy)
- Content Security Policy – this can help protect your website from cross-site-scripting attacks
This code snippet needs to be edited on a site-by-site basis, as it’s not a one-size-fits-all solution. Certain features of your site may break without the correct preparation!
# Security Headers - YOU MUST CHANGE the settings below to meet your needs - these ARE NOT ONE-SIZE-FITS-ALL
<ifModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-XSS-Protection "1; mode=block"
Header set X-Frame-Options "deny"
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header set Referrer-Policy "same-origin"
Header set Content-Security-Policy block-all-mixed-content
Header always set Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()"
</IfModule>
5. HTTPS / www / non-www redirects
If you’re an astute website owner, you’ll have noticed that some sites have www- and some sites do not. But all sites should have https:// in this day and age! There are pros and cons to both with and without www, which we won’t discuss here, but if you’re interested – this article explains it in more detail.
Basically, it doesn’t really matter that much whether you style your URL with or without the www, you just need to be consistent and have one redirect to the other.
Use whichever version of the following snippet applies to you. If you see an error saying “too many redirects” then remove the code and reach out to your host instead.
# Canonical HTTPS/non-WWW - replace example.com with your own domain
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1 [L,R=301]
</IfModule>
# Canonical https/ with www
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteRule (.*) https://www.%1/$1 [R=301,L]
</IfModule>
6. Disable Directory Browsing
Without this rule, the directories on your webserver are browsable and accessible by default. Many WordPress directories contain an empty .php file containing the opening tag followed by //silence is golden. This alone prevents directory browsing, but not all the directories on your webserver will have this file present.
Adding the following rule to your .htaccess file prevents directory browsing.
# Disable directory browsing
Options All -Indexes
htaccess Tips & Tricks
Here are some final tips and tricks you should know before making any changes to your .htaccess file.
Always use comments
Every line within .htaccess that starts with a # will be ignored. The # at the beginning of the line denotes a comment. You should always comment your own additions to .htaccess, for your own future reference and for the benefit of anyone else who works on your site it the future.
Deleting the file will not break your site
If you accidentally delete this file, your site will most likely remain accessible, but any custom rules added will no longer work, so your custom redirects, security and caching will be broken. If you depend on things like redirects, you’ll need to reinstate these as soon as possible to avoid users seeing errors.
Changing the WordPress Permalinks creates a htaccess file
In the WordPress dashboard, go to Settings > Permalinks, set your Permalinks to ‘plain’ and hit save, then set them back to ‘post name’ and hit save again. This will create a .htaccess file if you do not currently have one, it will add the following WordPress rules:
# BEGIN WordPress
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]
# END WordPress
TIP: Add any redirects before the # BEGIN WordPress line. The file is read from top-to-bottom, so redirects need to be above the WordPress Permalink block!
Always take a backup
If you find yourself needed to delete or edit the file and you want to be extra-cautious, always make a copy first. You can rename the file on the server from .htaccess to .htaccess.bak and reset your permalinks in WordPress to generate a new one.
All changes to .htaccess are instant, so you’ll instantly know if your changes have made the site inaccessible.
Do more with .htaccess
There is actually a lot more you can do with .htaccess, but I haven’t discussed them in a lot of detail here because each web host is different and some may override the following settings:
- Setting the PHP Memory Limit
- Setting the post_max_size and upload_max_filesize
- Require a password before entering the site (http authentication – a plain browser pop-up box – not a nicely styled login page!)
- Set other PHP settings
What have I missed? How are you using the .htaccess file to better control your website?
Related: WordPress Best Practice for 2022