Using and Abusing .htaccess

Apache’s .htaccess file is really powerful, but occasionally something of a dark art. Here are some things that I have used over the years, that work (for me anyway) along with hopefully detailed explanations of why they do what they do.


What’s up with the inclusion of Options +FollowSymLinks?

Lots of sites will tell you that Options +FollowSymLinks is a prerequisite for mod_rewrite, what is less clear is why fortunately for me the answer is clearly stated on:

In per-directory context (Directory and .htaccess), the Pattern is matched against only a partial path, for example a request of “/app1/index.html” may result in comparison against “app1/index.html” or “index.html” depending on where the RewriteRule is defined.

The directory path where the rule is defined is stripped from the currently mapped filesystem path before comparison (up to and including a trailing slash). The net result of this per-directory prefix stripping is that rules in this context only match against the portion of the currently mapped filesystem path “below” where the rule is defined.

Directives such as DocumentRoot and Alias, or even the result of previous RewriteRule substitutions, determine the currently mapped filesystem path.

So, it’s not actually a prerequisite in all circumstances but in most you’ll find you need it.

301 Redirects

For some reason I really struggled to get this to work and initially added it as two separate page rules in cloudflare (cloudflare doesn’t support RegEx in it’s page rules). This did work, but it wasn’t neat and the fact that it wasn’t working properly was irritating me, so I had another go and finally got there.

Here’s the file:

RewriteEngine = On
RewriteRule ^feed/?$ [R=301,L]

It redirects anyone coming to to my actual feed location ( regardless of whether they append the trailing slash. It’s a RewriteRule rather than a redirect because straight up redirects don’t allow for RegEx so I’m back to needing two rules.

Explanations of bits of the RewriteRule:

  1. Wrapping the url segment in ^ and $ tells the RewriteEngine only to match that bit of the URL. If you miss off the ending $ and the url you’re redirecting to includes the pattern then you end up in an infinite loop.
  2. /? tells it look for either 0 or 1 trailing slash.
  3. R=301 be a permanent redirect
  4. L stop if this rule matches - useful if you want to move from specific to general and don’t want later rules applying.