Spring Sale! Save 30% on all books w/ code: PLANET24
Web Dev + WordPress + Security

The .htaccess Rules for all WordPress Permalinks

Updated January 15th 2023: All code in this article is current with WordPress 6 and better. The permalink rules presented below should work with all versions of WordPress. That is, the current rules are backward compatible. </update>

I recently performed a series of tests on a fresh installation of WordPress to determine the exact .htaccess rewrite rules that WordPress writes to its .htaccess file for various permalink configurations. In the WordPress General > Permalinks settings, WordPress lists six options for permalink structure:

Plain              http://example.com/?p=123
Day and name       http://example.com/2016/06/30/sample-post/
Month and name     http://example.com/2016/06/sample-post/
Numeric            http://example.com/archives/123
Post name          http://example.com/sample-post/
Custom Structure   http://example.com/%postname%/

These default permalink options employ the following Structure Tags:

Plain              (permalinks disabled)
Day and name       /%year%/%monthnum%/%day%/%postname%/
Month and name     /%monthnum%/%postname%/
Numeric            /archives/%post_id%/
Post name          /%postname%/
Custom Structure   (user-defined structure)

You can read more about WordPress permalinks at WordPress.org.

Testing

For the test, we began by enabling the “Day and name” permalink configuration. After saving our changes, we downloaded the .htaccess file that is located in the root directory of our WordPress installation:

/wordpress/.htaccess

We then copied the rules and recorded them in this post (see next section). To verify that the .htaccess rules are the same for all types of permalinks, we tested each of the different permalink options and compared the results. Further, we tested the site for proper functionality during each round of testing.

Once we had determined the correct permalink rules for WordPress installed in its own directory, we repeated the entire test with WordPress installed in the site’s root directory. This test revealed that the permalink rules are different depending on the location of the WordPress installation. Otherwise, the permalink rules are identical, as explained below.

Results

So after much testing, we conclude the following results:

  • Given any WordPress installation, the .htaccess rules are identical for all permalink options.
  • The .htaccess rules only differ when WordPress is installed in its own directory vs. WordPress installed in the site’s root directory.

Surely this information is available elsewhere online, however we were experiencing several inconsistencies related to permalink structure that inspired us to determine for ourselves the precise .htaccess rules for all WordPress permalinks.

Without further ado, the .htaccess rules for all WordPress permalinks1 are either of the following2, depending on where WordPress is installed.

1) If WordPress is installed in the site’s root directory:

# 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

2) OR, if WordPress is installed in its own directory, /wordpress/:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /wordpress/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
</IfModule>
# END WordPress

Notice the only two differences between these two sets of rules: the value of the RewriteBase and RewriteRule directives. Specifically, when WordPress is installed in the site’s root directory, the value is /. Otherwise, if WordPress is installed in its own directory, the value is the name of the directory, which is /wordpress/ in this example. So if you have WordPress installed in its own directory, make sure to change /wordpress/ to the actual directory name.

Update

WordPress now (finally) has an official page about .htaccess at WordPress.org. There you can find the same permalink rules that are provided above. If they are different in any way, please let me know so I can update the article. Thank you.

Footnotes

1 These results are valid for standard permalink structures invoked via a standard WordPress install and may not operate effectively for non-standard or highly specialized configurations. We assume that if you are hard at work hacking and tweaking, you must know what you are doing.

2 Note that WordPress also adds several of inline comments when it automatically adds its permalink rules to your .htaccess file. The inline comments look like this:

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

The comments are included after the # BEGIN WordPress line. Because they are comments (i.e., begin with a pound sign #), they are ignored by Apache and have no effect on anything.

About the Author
Jeff Starr = Web Developer. Security Specialist. WordPress Buff.
WP Themes In Depth: Build and sell awesome WordPress themes.

96 responses to “The .htaccess Rules for all WordPress Permalinks”

  1. Perishable 2008/01/02 5:57 pm

    Excellent news, Adrian — I am glad to hear that the code worked for you. :)

    Happy New Year!

  2. Thank you, Thank you! I spent hours last night trying to figure this out and stumbled upon this today!

  3. My pleasure, Kyle — happy to help! Excellent looking site you have, btw ;)

  4. Hi Perishable,

    I’m having a similar issue with wordpress and .htaccess.

    I have multiple subdomains under one server. Within each subdomain is a WordPress blog. To avoid canonicalization, I rewrite domain.com to www.domain.com. Unfortunately, wordpress only works as a folder extension of highlevel domain. (eg. maindomain.com/subdomain/blog/)

    I tried a few tricks mentioned here and on WP.org, but to no avail.

    I was hoping with your experience you might have a quick solution.

    Thanks in advance,
    Scott

  5. Perishable 2008/01/20 9:48 am

    Hi scott,

    I want to help, but I am having some difficulty understanding your question.. What exactly are we trying to do here? I see that you are working with WP installs on various subdomains, and that you are redirecting non-www URLs to their www counterparts..
    — what am I missing?

  6. my site was hacked last night and as part of my research to restore it, two articles of yours came up. I noticed this because of your theme design. Thanks for posting the information. It’s been very helpful.

  7. Perishable 2008/02/26 6:10 pm

    My pleasure, sygyzy — happy to help! ;)

  8. Thank you so much for putting this up. I read it and the comments others left but I think my situation is a bit different and I was hoping you’d be able to help me out.

    My blog is located at http://domain.ca/blog. I have a .htaccess file in that folder with chmod 666

    I put your code from #2 above into the .htaccess file, changing the two instances of ‘foo’ to ‘blog’ (am I supposed to remove the #?)

    I activated date and name-based permalinkss then I went to my site and click on the title of an entry, with the hope that it would show only that entry on the page and the new improved permalink above. Instead, my header image disappeared and all the entries on the page are still visible.

    However, when I use the default permalinks and click on the title of the entry, the single entry shows up and I can still see my header image.

    I hope this makes sense. Would you have any idea why this is acting this way?

    Thank you for your time!

  9. Perishable 2008/03/25 1:46 pm

    Hi Jummy, I am not too sure about what the issue may be with your permalinks, but I can try to address a few concerns in hopes that something might click. First, you should not remove the # (pound signs) from the code. They are used in htaccess to denote a line containing a comment, which is information that should not be processed by the server. Second, keep in mind that the htaccess code provided in this article is the code used for all permalink formats (default, name-only, date-only, etc.), and should be an exact replica of the code that is automatically generated via WordPress. Finally, after you have implemented permalinks on your site, you may want to investigate any plugins, scripts, and/or theme code involved with the display of your header image. Beyond this, it is really difficult to say without a more thorough understanding of your particular WordPress setup and server environment, etc. In any case, I hope that helps provide some clues for you to consider. Good luck!

  10. Thank you very much! I think the whole process of submitting my problem to you and thinking on what you said helped me figure out my problem.

    My header image wasn’t showing up with individual posts because I had a relative link instead of the absolute link, so it wasn’t related to the above code not working.

    I appreciate your help. :)

  11. Perishable 2008/03/25 8:20 pm

    That’s great, Jummy! I am glad to hear that everything is working now. Thanks for the follow-up! Cheers :)

  12. So I’m curious if it is then possible to password-protect just one WordPress url. (WordPress has a post-level protection built-in but it stinks.) Would you not write this beneath your rewrite rules?

    # password-protect single file
    <Files index.php?p=67>
     AuthType Basic
     AuthName "This area is restricted to registered users"
     AuthUserFile /icslte/.htpasswd
     Require valid-user
    </Files>

Comments are closed for this post. Something to add? Let me know.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
Digging Into WordPress: Take your WordPress skills to the next level.
Thoughts
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
2024 is going to make 2020 look like a vacation. Prepare accordingly.
First snow of the year :)
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.