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

Stop WordPress from Changing .htaccess

[ Prevent WordPress Automatic .htaccess Modifications ] In a recent tutorial, I explain how to Stop WordPress from modifying .htaccess. That post explains several ways to prevent WordPress from making changes to .htaccess. This post explains an even better way that is safe, effective, non-invasive, re-usable, and super simple. I’ve been using it on my own sites now for a few years and it works flawlessly.

Keep it Simple

So this post will be kept quick and super simple, as all of the theory and .htaccess explanation can be found in the original article. So if you want more context, theory, and so forth, hit that post before continuing with the following tutorial. Also (and I always repeat this) make sure to make a backup copy of your .htaccess file before making any changes. That way if something weird happens you always can restore the original file.

Important

This technique only should be used when necessary to prevent WordPress from modifying any custom WP rules that may be in place. Otherwise if you are not using your own custom rules, it is recommended to not use this technique so that WordPress can update its rules automatically as needed.

The Magic Code

Before explaining how it works, here is the magic .htaccess code:

# PREVENT WP AUTO MODS
# @ https://m0n.co/08
<IfModule mod_ignore_wordpress.c>

# 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

</IfModule>

See below for code explanation and implementation.

Explanation

The thing to understand with this code block, is that it effectively does nothing. In the first line, we use <IfModule> to check for a non-existent/imaginary Apache module, mod_ignore_wordpress. Because that module never will exist on any server, Apache ignores everything inside of the <IfModule> container. So the net effect of these rules on anything is absolutely nothing.

Inside of the outer <IfModule> container, are the default, automatically added WordPress rules. The ones that WordPress adds to your .htaccess file when you enable Permalinks. These inner rules are the ones that WordPress will find and update automatically as it pleases. And because the inner rules are ignored, you can have custom WordPress rules in place elsewhere in your .htaccess, and they won’t be affected by any of WordPress’ automatic modifications.

Meme It

Admittedly the underlying logic may be a bit abstract, so here is a simple diagram that hopefully explains it more clearly:

[ Diagram showing default WP rules inside of disabling container ]The default added WP rules are disabled/ignored because they exist inside of a container that checks for a non-existent Apache module. Click image to view full-size (opens in new tab).

Implementation

Once you understand how the code works, what it does, etc., feel free to add to any WordPress site that makes sense. As mentioned, I’ve been using that code snippet for years on some of my sites. For example at Perishable Press Books, I use customized WordPress rules to integrate e-commerce and short-URL functionality. The rules are carefully crafted and mission critical, so the last thing I want is for WordPress to make any changes. It would be a disaster.

The Key

The KEY to using this code effectively is to make sure that your custom WordPress rules do NOT look like the default WordPress rules. You want them to look different so WordPress does not recognize them. I think specifically this means that you do not want to include the first and last lines:

# BEGIN WordPress
	.
	.
	.
# END WordPress

Do not include anything similar to those lines with your custom code. For example, I just use # WORDPRESS and omit any closing commentary like so:

# WORDPRESS
<IfModule mod_rewrite.c>
	RewriteBase /
	RewriteRule ^index\.php$ - [L]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	# Whatever custom rules, etc.
	RewriteRule . /index.php [L]
</IfModule>

I also think # CUSTOM WORDPRESS and similar make sense. Here is an example of some custom WordPress rules together with the “prevent mods” fix:

# PREVENT WP AUTO MODS
# @ https://m0n.co/08
<IfModule mod_ignore_wordpress.c>

# 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

</IfModule>

# CUSTOM WORDPRESS
<IfModule mod_rewrite.c>
	RewriteBase /
	RewriteRule ^index\.php$ - [L]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	# Whatever custom rules, etc.
	RewriteRule . /index.php [L]
</IfModule>

Notice how the first and last lines are unique for each of the rule blocks. WordPress will recognize and modify the first block and ignore the custom rules. It all is very simple and works beautifully.

For more in-depth discussion on this topic, check out the original post, Stop WordPress from modifying .htaccess.

About the Author
Jeff Starr = Web Developer. Book Author. Secretly Important.
WP Themes In Depth: Build and sell awesome WordPress themes.

8 responses to “Stop WordPress from Changing .htaccess”

  1. Why not just block the file permission or use the snippet from your other article?

    And why does WordPress ignore the code with the imaginary MOdul instead of reattaching it to the bottom because the code cannot be recognized?

    • As mentioned, I find this method to be simpler and equally effective at stopping WordPress from making changes to any custom rules that may be in play. And it’s not WordPress that ignores the fake module condition, it’s Apache. Which means that WordPress will recognize the rules within the container and modify them, leaving any custom WP rules untouched.

  2. Jim S Smith 2019/10/10 9:29 am

    One thing I found very effective:

    If you have your .htaccess file just above the “public_html”, and in the appropriate server “conf” file:

    # HTTPD.CONF EXAMPLE
    
    AllowOverride All
    
    DirectoryIndex index.php index.html
    IndexIgnore *
    AllowOverride None
    
    Require all granted

    This would have Apache2 simply ignore the .htaccess file in your “public_html” folder altogether. I have noticed that there are some web-hosting companies who allow the .htaccess above the “public_html” folder too!

    If you are hosting on a shared account, some accounts may allow you to make changes to a few of the server-side settings from a control panel applet.

    ( BTW: This trick on my VPS helped speed up my website loading times a little too! )

    – OR –

    You could just change the “UGO” file access bits like so:

    chmod 0555 .htaccess

    ( Or – “chmod ugo-w .htaccess” )

    – Jim

    • Jeff Starr 2019/10/11 9:57 am

      Hey Jim, thanks for the comment, but part of your Apache code (e.g., the IfModule containers) were removed by WordPress. This is why it is important to wrap any code with the appropriate tags, as explained clearly in the site’s official Comment Policy (look under “Including HTML in Comments”). Thanks!

      • Jim S Smith 2019/10/11 1:09 pm

        Okay.

        Perhaps entity-encoding the affected parts before posting would help that?

        – Jim

      • Jeff Starr 2019/10/12 1:27 am

        No my friend, simply wrap your code with the appropriate tags and we’re all good.

  3. Hi. I tried this on a Litespeed server but it seems to just ignore the check and load the rules from it anyway, while the latter just gets completely ignored. Any thoughts?

    # PREVENT WP AUTO MODS
    # @ https://m0n.co/08
    
    # this gets loaded anyway
    
    # BEGIN WordPress
    
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    
    # END WordPress
    
    # CUSTOM WORDPRESS
    # this does nothing
    
    	RewriteBase /
    	RewriteRule ^index\.php$ - [L]
    	RewriteCond %{REQUEST_FILENAME} !-f
    	RewriteCond %{REQUEST_FILENAME} !-d
    	# Whatever custom rules, etc.
    	RewriteRule . /index.php [L]
    • Jeff Starr 2019/12/20 1:27 am

      I’m not sure. The rules work on Apache servers, so it may be an issue with Litespeed?

      Also, it looks like the IfModule containers were stripped from your comment. See this previous comment for more infos.

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.