Force reload of updated CSS and Javascript files with unique filenames
Posted March 20th, 2009 in Apache, HTML and CSS, Javascript and PHP
When a CSS or Javascript file is changed the visitor's browser needs to get the latest copy of the file to reflect the changes, but it will have been cached and may cause rendering or functionality issues depending on the changes. To force reloading of the CSS and Javascript file the files should be renamed each time they are changed; this can be automated by using PHP to add the timestamp of the file into the filename.
I've posted about doing this previously using the timestamp as part of a query string, but it would appear this method has implications with proxy servers often not caching the files due to the query string. I found that post thanks to the comments to David Walsh's recent post in which he suggests always writing out the timestamp to the Javascript or CSS filename.
The problem with doing that is it will force the browser to always download a copy of those files on every page request which somewhat defeats the purpose of caching. Instead I'll show here how to make the filename unique based on the last time it was modified, and without having to use query strings or rename the file thanks to a little bit of .htaccess magic.
If the stylesheet is css/main.css and the Javascript file js/common.js you can write out the appropriate tags into your page like this:
<link rel="stylesheet" type="text/css" href="/css/main.<?php echo filemtime('/path/to/css/main.css'); ?>.css" />
<script language="javascript" src="/js/common.<?php echo filemtime('/path/to/js/common.js'); ?>.js">
</script>
This will result in filenames in the HTML code like this:
/css/main.1237440708.css /js/common.1237441675.js
Now we need some rewrite rules in an .htaccess file to rewrite the time stamped version of the filenames to the actual filenames:
RewriteEngine On RewriteRule ^css/main.[0-9]+.css /css/main.css [L] RewriteRule ^js/common.[0-9]+.js /js/common.js [L]
Now a request for css/main.[numbers].css will actually result in css/main.css being served.
The above example requires a rule for every stylesheet and Javascript file but we could instead use regular expressions so any CSS or Javascript file with .[numbers]. in it will be rewritten:
RewriteEngine On RewriteRule ^css/(.*)\.[0-9]+\.css /css/$1.css [L] RewriteRule ^js/(.*)\.[0-9]+\.js /js/$1.js [L]
And finally, both could be combined into a single rule:
RewriteEngine On RewriteRule ^(css|js)/(.*)\.[0-9]+\.(.*)$ /$1/$2.$3 [L]
Now you can simply add any additional directory prefix into the first backeted part to apply the rules to those too.
Related posts:
- Add an offsite link icon after external links with CSS (Friday, March 27th 2009)
- Replacing text with Javascript (Tuesday, February 10th 2009)
- Find the index of a string within a string with Javascript (Friday, November 28th 2008)
- Using Internet Explorer Conditional Tags for Style Sheet Selection (Wednesday, May 21st 2008)
- Using the HTTP_REFERER variable with PHP (Friday, April 18th 2008)
- Formatting Dates with PHP (Thursday, December 20th 2007)

Comments
blog comments powered by Disqus