Have you ever pushed out an update that included modifications to scripts or styles and then later had to tell someone to clear their cache or do a hard refresh in order to see the updates? There is actually a very simple way to avoid this scenario and force the browser to display the updated scripts and styles, even when a caching plugin is in use.
When using wp_enqueue_script() and wp_enqueue_style(), there is a $ver parameter (version) that allows you to pass a file version. This version number is used to determine if a new version should be displayed or not. By default, if you do not include the version number, WordPress automatically gives your script or style the same version number as the current install of WordPress.
Let’s assume that we have loaded a page that has a script set to version 1.0. After loading this script gets cached, so the next time we load the page, we’re actually viewing the cached version. If on our next visit, however, WordPress sees that the script is now version 1.1, it will force the browser to reload the script fresh instead of from cache. This ensures that the new version is always used.
If you have a large plugin or theme, keeping track of script and style version numbers can be difficult, so what I like to do is simply pass the same version number as the plugin or theme. This works really well because anytime an update is released, I have confidence that the new scripts / styles will be used. If no changes were made to any scripts or styles, no harm is done, but if changes were made, they will be displayed.
It’s really great because this even works with caching plugins installed, such as W3 Total Cache or WP Super Cache.
I usually define a constant that holds my plugin version number, like so (example take from Easy Digital Downloads):
1 | define( 'EDD_VERSION', '1.3.2' ); |
In my script loader, I then use it like so:
1 2 | wp_enqueue_script( 'edd-ajax', EDD_PLUGIN_URL . 'includes/js/edd-ajax.js', array( 'jquery' ), EDD_VERSION ); wp_enqueue_script( 'edd-validation', EDD_PLUGIN_URL . 'includes/js/form-validation.js', array( 'jquery', 'jquery-validation' ), EDD_VERSION ); |
Anytime I push out an update, I simply update my EDD_VERSION constant with the new version number and all scripts / styles then use this as their new version.
Thanks Pippin! This was happening to me the other day and I knew it, just wasn’t sure how to make it simple.
Something that annoys me during development is that I’ll make a css change, reload, realize I need to increment the number, reload, etc.
Is there a way to make it NOT cache while I making changes every couple minutes?
I would just disable caching entirely while doing that. Incrementing your version number during dev probably isn’t a great idea.
Good tip! http://wordpress.org/extend/plugins/versionit/ is pretty handy too π
That’s a great idea! Love it π
Several browsers and proxies do not cache resources that have a query string in the URI (Revving Filenames: donβt use querystring) so it might be better to include the last modified time in the filename itself.
A few month ago I created the Minit plugin which combines all CSS and JS files into one and stores them in the uploads/minit folder. It works only with scripts and files that are enqueued using the standard enqueue methods. It checks the filemtime of every enqueued file on every request and includes that information in the generated filename. It would be great if more people could test this plugin.
The plugin looks good! Also take a look at the one Zach just released: http://wordpress.org/extend/plugins/versionit/
Thanks for the detailed article. I have been using random version numbers as I dont have much idea about it. From now will implement this and in one go version number will be updated for all scripts and CSS files. Kudos Pippin.
You can actually eliminate the need to use a plugin version constant by utilising PHP’s
filemtime()
function. Mark Jaquith explained its use for stylesheets here and it’s easy to convert for use within your plugin usingplugin_dir_path()
.That works really well too, though it’s really the exact same thing. The difference is that you don’t need the constant, but if you already have a constant defined, then there isn’t any extra.