How can I prevent WordPress and plugins from overwriting my .htaccess
file? I use Wordpress to set the structure of my permalinks; so I doubt it is practical to deny all permissions to the file.
If it is unlikely that WordPress is responsible for overwriting the file, advice on determining what is responsible would be helpful.
I recently added these rules to .htaccess to redirect traffic to HTTPS.
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
One day later, I found that .htaccess had reverted to its previous state. Following is a portion of the .htaccess file as I intend it.
# BEGIN W3TC Page Cache core
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} =on
RewriteRule .* - [E=W3TC_SSL:_ssl]
RewriteCond %{SERVER_PORT} =443
RewriteRule .* - [E=W3TC_SSL:_ssl]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule .* - [E=W3TC_ENC:_gzip]
RewriteCond %{HTTP_COOKIE} w3tc_preview [NC]
RewriteRule .* - [E=W3TC_PREVIEW:_preview]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} =""
RewriteCond %{REQUEST_URI} \/$
RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle) [NC]
RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_SSL}%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" -f
RewriteRule .* "/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_SSL}%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" [L]
</IfModule>
# END W3TC Page Cache core
This code redirects traffic with a status of 301 as expected, until the .htaccess file is overwritten.
--Update-- By placing comments in several sections of the .htaccess file and observing which one was overwritten, I found that plugin W3 Total Cache overwrote the entirety of the section commented with
# BEGIN W3TC Page Cache core
How can I prevent WordPress and plugins from overwriting my .htaccess
file? I use Wordpress to set the structure of my permalinks; so I doubt it is practical to deny all permissions to the file.
If it is unlikely that WordPress is responsible for overwriting the file, advice on determining what is responsible would be helpful.
I recently added these rules to .htaccess to redirect traffic to HTTPS.
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
One day later, I found that .htaccess had reverted to its previous state. Following is a portion of the .htaccess file as I intend it.
# BEGIN W3TC Page Cache core
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} =on
RewriteRule .* - [E=W3TC_SSL:_ssl]
RewriteCond %{SERVER_PORT} =443
RewriteRule .* - [E=W3TC_SSL:_ssl]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule .* - [E=W3TC_ENC:_gzip]
RewriteCond %{HTTP_COOKIE} w3tc_preview [NC]
RewriteRule .* - [E=W3TC_PREVIEW:_preview]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} =""
RewriteCond %{REQUEST_URI} \/$
RewriteCond %{HTTP_COOKIE} !(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle) [NC]
RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_SSL}%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" -f
RewriteRule .* "/wp-content/cache/page_enhanced/%{HTTP_HOST}/%{REQUEST_URI}/_index%{ENV:W3TC_SSL}%{ENV:W3TC_PREVIEW}.html%{ENV:W3TC_ENC}" [L]
</IfModule>
# END W3TC Page Cache core
This code redirects traffic with a status of 301 as expected, until the .htaccess file is overwritten.
--Update-- By placing comments in several sections of the .htaccess file and observing which one was overwritten, I found that plugin W3 Total Cache overwrote the entirety of the section commented with
# BEGIN W3TC Page Cache core
Share
Improve this question
edited Oct 22, 2017 at 18:01
Jacob Quisenberry
asked Oct 9, 2017 at 3:19
Jacob QuisenberryJacob Quisenberry
1951 silver badge6 bronze badges
5 Answers
Reset to default 7If you place your "custom" directives outside of any # BEGIN ...
/ # END ...
comment markers then WordPress (and plugins) should not overwrite them when they update. (Of course, if you have plugins that don't "play nice" then they could do anything to .htaccess
if you let them, so you would need to do something like what @haz suggests in this case.)
In your case, you can simply place those directives above the # BEGIN W3TC Page Cache core
comment. For example:
# Custom directives
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# BEGIN W3TC Page Cache core
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} =on
RewriteRule .* - [E=W3TC_SSL:_ssl]
:
You don't need to repeat the RewriteEngine On
directive (providing it occurs somewhere in the file). And your directives are not using RewriteBase
anyway - but again, RewriteBase
should only occur once in the file. (The last instance of each of these directives is what controls the entire file.)
(Aside: The parentheses around the RewriteRule
pattern are superfluous in your directive.)
Wordpress will definitely rewrite your .htaccess file under certain circumstances, such as if you change Permalinks.
Like you, we have a bunch of custom things in out .htaccess file, which I'd prefer to leave in the hands of our devOps guys rather than Wordpress.
The easiest way if you have access to the server is to change the file permissions on .htaccess
& chmod a-w .htaccess
This removes write access for all users. If you don't have shell access to your Wordpress instance, your hosting provider might provide a file explorer type setting where you might be able to alter your file permissions.
Alternatively, you could change the file ownership:
& chown root:root .htaccess
& chmod 644 .htaccess
This may not work depending on your Apache user settings, and is almost certainly not an option provided by your hosting provider.
A third option you can use, which once again requires you to be in control of your server, is to put your immutable settings (such as as your HTTPS rewrite) into a different include file in your VirtualHost settings.
<VirtualHost *>
ServerName www.mysite.com
DocumentRoot /var/www/mysite.com/wordpress/
Include /var/www/mysite.com/custom-apache-settings.conf
</VirtualHost>
As haz stated in his answer, WordPress will (and should be able to) overwrite the .htaccess.
You can use mod_rewrite_rules filter to add you own, though. To keep it simple, you could add a file .htaccess.custom, put your rules in there and add its content to $rules in the filter. Don't forget to return $rules.
A more elegant answer is to block WordPress from writing to the .htaccess in between the # BEGIN WordPress and # END WordPress blocks. Coincidently it will also prevent any other plugin from writing to that section.
# BEGIN Custom Block Code
<IfModule mod_ignore_wordpress.c>
# BEGIN WordPress
# 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.
<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
</IfModule>
# END Custom Block Code
There are multiple possibilities to intervene into WordPress' .htaccess
file manipulations:
To prevent WP completely from editing your existing
.htaccess
file, it's best to change or remove the write permissions or owner:group. WP checks if the file is writable and if not, it doesn't try to change it.To stop WP from even creating a
.htaccess
file or if you can't change permissions on the server and want to prevent WP from editing your file, add aflush_rewrite_rules_hard
filter returning false in your plugin's code or theme'sfunction.php
// Please leave .htaccess file untouched
add_filter('flush_rewrite_rules_hard','__return_false');
- When writing a plugin or theme that needs some extra config in the
.htaccess
file, use themod_rewrite_rules
filter to add your config lines.
Use this in your plugin or theme'sfunction.php
// Add extra config lines to .htaccess
add_filter( 'mod_rewrite_rules', function( $rules ) {
return $rules . '
# My rules ...
# ... go here
';
} );
- You want to see all changes WP is doing in your
.htaccess
but don`t want them to apply you can add this filter.
// Comment out all configuration WordPress adds to .htaccess
add_filter( 'mod_rewrite_rules', function( $rules ) {
return '# ' . str_replace("\n", "\n# ", $rules);
}, 100 );