9

I'm learning to maintain my own WP site. After a lot of reading I ended up with my "complete" htaccess file that looks something like this

DirectoryIndex index.php

# Disable directory listings
Options -Indexes
# PROTECT htaccess file
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
# PROTECT WP-CONFIG
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>

# Block Hotlinking
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER}     !^$
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} \.(jpeg|jpg|png)$           [NC]
RewriteCond %{HTTP_REFERER}     !^http://([^.]+\.)?example\. [NC]
RewriteCond %{HTTP_REFERER}     !google\.                       [NC]
RewriteRule \.(gif|jpeg|jpg|png)$  http://example.com/wp-content/images/hotlink.jpg [F,NC,L]
</ifModule>

# redirect Mobile from Blogger
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} ^m=1$
RewriteRule (.*) $1? [R=301, L]
</IfModule>

# Block the include-only files.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>

# 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

Most of it is composed by copying, adapting and pasting code from various sources. Since I'm a self-taught newbie, I have the following questions:

  1. Does the order of the code snippets play a role? Is it correct in the above example?

  2. Are all these repetitive

    <IfModule mod_rewrite.c>
    RewriteEngine On
    ...
    </IfModule>
    

correct, or should one somehow combine them and avoid multiple calls to it?

1 Answer 1

16
  1. Does the order of the code snippets play a role? Is it correct in the above example?

Yes, the order of the directives in Apache config (.htaccess) files can be important. In fact, simply having directives in the wrong order is a common cause of error.

With WordPress, people often make the mistake of including canonical redirects (ie. HTTP to HTTPS and non-www to www etc.) and/or blocking directives after the WordPress (front-controller) directives - this is unlikely to work (although this does depend on the directives/modules used).

Primarily you should always have external redirects before internal rewrites.

In what you have posted, the order of the directives look OK.

You should note that different modules (mod_rewrite, mod_alias, etc.) are largely independent and run at different times. But for each module the directives execute top to bottom.

RewriteEngine On

It doesn't matter too much, but RewriteEngine only needs to occur once in the file, preferably at the top, before any mod_rewrite directives (just because it's more logical and easier to read that way). However, it can be placed anywhere in the file and it will still work (at the expense of readability)! Strictly speaking, if you have multiple RewriteEngine directives then the last one wins and controls the entire file. So, if the very last RewriteEngine directive was RewriteEngine Off then it would be Off for the entire file!

<IfModule mod_rewrite.c>

In the code you have posted, checking if the module is loaded multiple times is unnecessary. In fact, you probably don't need to check this at all. Can your site run "OK" (or do you still wish to allow access) without mod_rewrite enabled? If not, then there is no need to check for this - it should simply fail with an appropriate error state.

See my answer to the following Webmasters question for more detail regarding this: Is Checking For mod_write Really Necessary?

RewriteBase /

Having multiple RewriteBase directives should ideally be avoided, although it will work OK in this instance. The last RewriteBase directive in the config file wins and controls the entire config file (like the RewriteEngine directive mentioned above). If you include a RewriteBase directive then it should really be included just once immediately below the RewriteEngine directive.

As it happens, apart from the slight error mentioned below, you don't actually require the RewriteBase directive in the file posted above. (The RewriteBase directive overrides the directory-prefix that is added to relative path substitutions in the RewriteRule. You don't have any relative path substitutions - apart from that mentioned below.)

Having repetition in .htaccess is common when multiple modules are automatically editing it. By hand coding the config file (recommended), this can be avoided.

RewriteRule (.*) $1? [R=301, L]

This line is in error. With it being an external redirect, you should really have a slash prefix on the substitution ie. /$1? (although the RewriteBase directive defined elsewhere is actually saving you - although this looks like a bit of "luck" rather than being intentional).

But, more importantly, you should remove the space in the RewriteRule flags ie. [R=301,L]. A space is a delimiter in Apache config files (ie. very special). Having a space here will result in a 500 Internal Server error, since the last argument (the flags) terminates prematurely and is seen as [R=301, - which is syntactically invalid.

3
  • I greatly appreciate it! I lost 3 hours till I found by trial and error that space was ruining my redirect. Never noticed the missing /. What does DirectoryIndex index.php do- is it needed?
    – IXN
    Commented Dec 7, 2015 at 9:22
  • 1
    The DirectoryIndex is the file that is served when you request a bare directory. eg. When you request example.com/directory/, it will attempt to serve example.com/directory/index.php, by internally rewriting the request (the URL in the browser's address bar does not change). You don't necessarily need this in .htaccess unless you want to change the default, as it's usually defined in the Apache config. (Incidentally, the Apache default is DirectoryIndex index.html.) You can specify multiple files in this directive and they will be searched for in order.
    – MrWhite
    Commented Dec 7, 2015 at 10:25
  • Really good answer thanks for clearing up that the last RewriteEngine wins
    – JimLohse
    Commented Oct 4, 2022 at 21:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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