Greg Aker

What's Your .htaccess?

Filed in: Performance, PHP

November 1, 2010

I don't use a whole lot of Apache anymore for my personal stuff, but when I do, here's my basic .htaccess.

Some people might say:

"Woah Greg, what the heck, you aren't gzipping your static content you hosehead!"

Well, I have an answer for you. See, gzipping can be a CPU-intensive operation on the web servers. If you're on a Cheap VPS, a la Linode, Rackspace Cloud, Slicehost, etc you're trying to squeeze every bit of CPU power out of it. Or on the flip side, an awesome host like EngineHosting (yes, I do work there. :) ) is gzipping content at the Load Balancers, so you're not going to be beating up on the web servers. Make sense?

FileETag None

<IfModule mod_rewrite.c>
    RewriteEngine On
    # Force www
    RewriteCond %{HTTP_HOST} ^example.com$ [NC]
    RewriteRule ^(.*)$ http://www.example.com$1 [R=301,L]

    # Uncomment to Remove www, but comment the above 2 lines out. :)
    # Otherwise the world will end
    # RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
    # RewriteRule ^(.*)$ http://example.com$1 [R=301,L]

    # Removes index.php
    RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php/$1 [L]
    # If 404s or "No Input File" errors, or every page give the same thing
    # make it /index.php?/$1 above -- Just adding the question mark
</IfModule>

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/html "access plus 1 second"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/jpg "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType text/javascript "access plus 1 month"
    ExpiresByType application/pdf "access plus 1 month"
    ExpiresByType application/x-download "access plus 1 month"
    ExpiresByType application/x-javascript "access plus 1 month"
    ExpiresByType application/x-shockwave-flash "access plus 1 month"
</IfModule>

Another couple things to note, I generally don't bother with the 'Include' or 'Exclude' methods listed on the ExpressionEngine Wiki. Unless I have a situation where I can see Apache being affected by using the File & Directory check method, I think it's a pain in the butt to keep track of everything in the .htaccess, and mistakes can happen.

A couple points: FileETag NoneThis unsets ETags, which is a header attached to your content by Apache. For more information on ETags, read about it. I'm choosing to either force www, or remove www. I generally choose to force it. If it's good enough for our favorite search engine, it's good enough for me.

ExpiresByType - The websites are dynamic, but the static resources probably don't change all that much. So we tell the browser to cache the html page itself for 1 second, and send a 1 month caching header on everything else.

Now, I do realize that Yahoo and Google say to do it longer, but I am asserting that for websites like us, it does not matter. We don't, nor will we probably ever pull 1/1000th of the traffic of those sites. It's not very likely that someone is going to still have images from our website in their cache 5-6 weeks from now. With Yahoo or Google, that's a different story.n So really, I could probably get away with a week or even a day here, but you get the general point. :)

I find this .htaccess to be solid for me on CodeIgniter, WordPress, ExpressionEngine or Zend Framework projects.So what do you do?