Cache-busting HTML Pages

17 Feb
February 17, 2014

I ran into a scenario twice this week where I pushed updates to a site and it was important that the changes were reflected immediately. Most of the time it isn’t a big deal if a change takes an hour or so before someone sees them without a forced refresh (Shift + Refresh). Indeed, according to the Apache Caching Guide, “The default expiry period for cached entities is one hour.” This time, I was making a change, and then sending out an email to all our subscribers linking directly to the change. I only got the go-ahead to push the change live about 5 minutes before the email was supposed to be sent. On a final test of the email blast, I noticed the link went to the old version; the changes weren’t being shown until after I refreshed a few times.

This presented 2 problems:

  1. I know how to cache-bust CSS and Javascript resources by appending a query string to their path (like main.css?v=2), but that didn’t do me any good if a stale version of the HTML was being served.
  2. I only had a limited number of tests on machines in the building to determine whether my fix worked. As soon as the browser loads the new version of the site, there’s no longer any way to simulate the problem with that Browser + Machine combination without reverting changes on the server, which wasn’t an option.

Nothing useful showed up for my initial search: ‘Cache bust HTML’ (hence the title of this post… take note, Google). After a little more digging a colleague and I came up with the solution of sending back a Cache-Control header that forced resources matching *.html to expire after 1 minute. This worked! Here’s how I did it.

The Solution

Start by SSHing into your server and making sure you have the `headers` apache module enabled. You can check in the `mods_enabled` folder in your apache config (ours is at /etc/apache2/mods_enabled on our Ubuntu box). If it isn’t enabled, run `a2enmod headers` and follow the instructions to restart apache. If you’re on a shared hosting plan, you may not be able to check or change these kinds of settings. You can still try the code below, which will fail gracefully since it’s wrapped in the IFModule condition.

Next, add the following to your .htaccess file:

Change the max-age parameter to whatever is reasonable for you. The max-age is in seconds, so I have it set for one minute above. Once you apply this, it should take effect immediately. To verify, open up the Network tab in your developer tools, refresh, and inspect the response headers for the page you’re targeting. You should see the Cache-Control header with the max-age that you set in your .htaccess!

The next morning, I changed this to 3600, or 1 hour. There’s no need to always set the max-age to 1 minute, but I left the whole block in so I could quickly update the number in case I need to use this again.

It’s worth noting there are plenty of ways to set headers depending on your project server configuration. This was for a static site served by apache, so using .htaccess made sense for us. There are other ways to do this, research the best way to set headers for your project and focus on the Cache-Control header above.

Will Dages

Will is the Manager of Web Development at Findaway World.

More Posts - Twitter - Google Plus

Tags: , , , ,
© Copyright 2017 Findaway. All rights reserved.