Keep WordPress From Overwriting .htaccess Rules

    June 11, 2007

For as long As I care to remember I’ve been having issues with my WordPress .htaccess file.

.htaccess file is a small Apache file that lets you do all sorts of funky things with requests made to your server. It’s also one of SEO’s best tools. I have a lot of custom 301 redirects set up, including a redirect which makes my site available only via the www subdomain.

WordPress Permalinks

Well WordPress has a habit of rewriting the .htaccess file to allow some of the SEO-friendly URLs you regularly see (also known as ‘permalinks’). And each time it does so I lose my rules. It’s a royal pain in the arse and when this happened just the other day I thought I’d take the time to fix this for once and for all. I had to dig through the WordPress Codex to see what was causing all the trouble. save_mod_rewrite_rules() is the culprit. That little function, and my own ignorance of how WordPress processes the .htaccess file.

The solution

As with most solutions it’s really very simple. As with most simple solutions it’s only simple if you know about it. So here it is:

WordPress .htaccess file looks like this:

# BEGIN wordpress
<ifmodule mod_rewrite.c>
rewriteEngine On
rewriteBase /
rewriteCond %{REQUEST_FILENAME}!-f
rewriteCond %{REQUEST_FILENAME}!-d
rewriteRule . /index.php [L] </ifmodule>
# END wordpress

Now here’s the really important bit:

Never place your own rules within the ‘wordpress’ block

The WordPress block is the bit that starts with # BEGIN wordpress and ends with # END wordpress. My mistake was to place my rules within this block (after the rewirteEngine On line). This seemed the sensible thing to do – after all rewrite rules must come after rewirteEngine On, and my understanding was not to repeat this command.

How WordPress rewrites .htaccess files

When WordPress rewrites the .htaccess file it does so by first checking that the file is writeable, then exploding the file using the # BEGIN and # END strings. Anything outside of those markers should be left intact after WP rewrites the file.

In my case I had to add a new block with a second rewirteEngine On so that Apache wouldn’t break (although I don’t think this is strictly the correct way to write the file). Here’s what my new revised .htaccess file looks like:

<ifmodule mod_rewrite.c>
RewriteEngine On
[... ]Funky custom rules go here[ ...] </ifmodule>
# BEGIN WordPress
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L] </ifmodule>
# END WordPress

Perhaps the WordPress folk could add an additional comment into the .htaccess file that explains this better?

Well there you have it – how to stop WordPress overwriting your custom .htaccess file rules.