WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I set up Wordpress as a multisite and as part of the steps, it gave some instruction to update and replace the .htaccess file.

Wordpress instructed me to replace the htaccess with this:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]

However this caused some jquery on a plugin to break.

I thought it might be useful, but could someone help provide some insight into what each of these lines does?

In particular this line:

RewriteRule ^(.*\.php)$ $1 [L]

As, if I remove this line, my plugin works fine.

Thanks in advance :)

share|improve this question
Is this a plugin that you wrote? A public one in the Repository? Or a premium one? – brasofilo Feb 11 '13 at 19:25

I've been looking for details on why that line is suggested for a multisite install using subdomains as well. I actually question if both of these are relevant for a subdomain install:

RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]

In a sub-directory install the rules are setup slightly different to strip the sub-directory name from the request to be something like:

RewriteRule  ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule  ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]

I'm seeing a redirect loop in my error logs and it's caused by the first version of these rules since the replacement text is identical to the original text. I found some evidence that some versions of mod_rewrite will detect that the original and new text are the same and skip the re-insertion of the result. (Not sure which of the many links I've been reading at this point.)

I see no value in rewriting a URI to be identical to original and thus causing the link to be reinserted into the rewrite engine. With the rules removed I get the expected 404 page instead of a redirection loop that ends in a 500 server error when the redirection limit is exceeded.

Separate note, I think that the suggested sub-directory version is also broken. Because it uses ? for the sub-directory portion, it will loop on an input URL like no-such-file.php. Matching on the sub-directory portion should not allow for zero copies so the rule should likely be:

 RewriteRule  ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]
 RewriteRule  ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]

A similar conclusion is found here: http://wordpress.stackexchange.com/a/73185/27576

share|improve this answer
I think that the suspect rewrite rules may exist to handle multi-site installations served from the site root, but physically located in a subdirectory (i.e. mysite.com/wordpress accessed transparently from mysite.com). If RewriteBase is anything other than /, then the rewrite engine will be using the apparently redundant rules to perform significant rewrites. I haven't confirmed this, though - still it's strange that WordPress might suggest these patterns in non-subdirectory WordPress installations. – bosco Sep 12 '15 at 4:04

RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
Redirects http://yourdomain.ext/wp-admin to http://yourdomain.ext/wp-admin/

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
Conditional logic, check if the requested filename is not a existing file (-f) or directory (-d).

RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
Redirect wp-content.ext, wp-admin.ext and wp-includes.ext to the file itself, whether this file exists or not.

RewriteRule ^(.*\.php)$ $1 [L]
Redirect any .php file to that file, whether the file exists or not.

RewriteRule . index.php [L]
Redirect everything to index.php.

Basically, the .htaccess redirects every requested file to that particular file, and every directory to index.php.

Read over the detailed mod_rewrite documentation for the details of how the rewrite engine works.

share|improve this answer
Regarding the RewriteCond - It's my understanding that the -f [OR] -d will match if the file or directory does exist. The RewriteRule on the subsequent line (RewriteRule ^ - [L]) would fire (^ matches any URI) and terminate re-insertion of the URI to the engine (- means no substitution and [L] meaning this is the last rule to be applied on this iteration). – KenB Jan 8 '15 at 18:17

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.