Skip to content

.htaccess generator for WordPress

Choose what you want the server to do and get a complete .htaccess: WordPress's own block, with redirects, closed files, headers and compression above it. Built in your browser.

Where WordPress is

A slash for a site at the top of its domain. For a site in a folder, the folder as the address shows it, such as /blog/.

https and the site's name

Only once the site loads over https. Until then, leave this off.

What to close

The log WordPress writes when debugging is on, which anyone can otherwise read by its address.

Only if nothing uses it. Jetpack and the WordPress mobile apps do.

IP addresses that do not change, such as an office's, separated by spaces. Not for a site where customers or members log in.

What to add

X-Content-Type-Options, Referrer-Policy and X-Frame-Options.

Pages, styles and scripts are sent smaller. Many hosts already do this for the whole server.

Works only where PHP runs as an Apache module. Elsewhere the lines are skipped, and the host's own setting decides.

.htaccess
# Do not list the files of a folder that has no index page.
Options -Indexes

# Files no visitor needs to ask for.
<Files "wp-config.php">
    Require all denied
</Files>
<Files "debug.log">
    Require all denied
</Files>

# Headers that tell a browser how to treat the site's pages.
<IfModule mod_headers.c>
    Header onsuccess unset X-Content-Type-Options
    Header always set X-Content-Type-Options "nosniff"
    Header onsuccess unset Referrer-Policy
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header onsuccess unset X-Frame-Options
    Header always set X-Frame-Options "SAMEORIGIN"
</IfModule>

# Compress text on its way to the visitor.
<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml
        AddOutputFilterByType DEFLATE text/javascript application/javascript application/json
        AddOutputFilterByType DEFLATE application/xml application/rss+xml application/atom+xml
        AddOutputFilterByType DEFLATE image/svg+xml font/ttf font/otf application/vnd.ms-fontobject
    </IfModule>
</IfModule>

# BEGIN WordPress
<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
Built in your browser. Your rules come first, then WordPress's own block.

What this file is

.htaccess is a file the Apache web server reads from the site's main folder on every request. WordPress writes a block of its own into it, between # BEGIN WordPress and # END WordPress, which is what makes permalinks work. The file built here is that block, with the rules you chose above it.

WordPress rewrites its own block when you save the permalink settings, so a rule placed inside it is lost. That is why yours go above it.

How to use it

  1. Download a copy of the .htaccess the site has now. It is your way back.
  2. If that file holds rules a plugin added, such as a caching plugin's, keep them: copy them into the new file, above WordPress's block.
  3. Save the file built here, rename it to .htaccess, with the dot and nothing after it, and upload it over the old one.
  4. Open the site, a post, and the login page, in a private window.

If every page shows an error after the upload, the server could not read a line: put the old file back, and see how to fix the 500 internal server error. If you are sent round in a circle, see how to fix ERR_TOO_MANY_REDIRECTS.

What each choice does

Rules for headers, compression and the upload limit are wrapped so that a server without the module they need skips them and carries on. A rule that is skipped does nothing, so check that each one took effect: the site health check shows the headers a page sends, and the redirect checker shows each hop of a redirect.

Where it does not apply

Only Apache, and servers that read its files such as LiteSpeed, use .htaccess. nginx does not: use the nginx server block generator. On a network of sites (multisite), WordPress's own block is different from the one here: keep the one WordPress gave you.

Nothing you type here is sent to us. The file is built in your browser.

Common questions

Do I need a new .htaccess at all?
Not if the site works and you want none of these rules. WordPress writes its own block by itself when you save the permalink settings. This tool is for adding rules around that block, or for putting back a file that was lost or damaged.
Why do my rules go above WordPress's block and not inside it?
WordPress owns the lines between its two markers and writes them again whenever the permalink settings are saved. Anything else placed between the markers is lost at that moment.
I restricted the login page and now I am refused. What do I do?
Your own address has changed, or a proxy in front of the site is showing the server its address in place of yours. Remove the block that names wp-login.php, through your host's file manager or over SFTP, and the login page opens again.
The file I saved is named htaccess.txt. Why?
A file whose name begins with a dot is hidden on most computers, and a file you cannot see is hard to upload. Rename it to .htaccess once it is on the server.

Would you rather not edit it yourself?

Tell us what you want the site to do, or what it does now. We reply with the cause and a fixed quote. The diagnosis is free.

Get a free diagnosis