WordPress CSS/JS Cache Not Updating – Versioning Fix
Solve CSS and JS cache issues in WordPress using wp_enqueue_style, wp_enqueue_script, and smart versioning techniques.
Why CSS and JS Cache Doesn’t Update
When you make changes to your CSS or JavaScript files in WordPress, visitors often still see the old version. This happens because browsers, CDNs, and caching plugins store (cache) these assets to speed up page loading. The browser uses the file’s URL to decide whether to fetch a new copy. If the URL stays the same, the browser assumes the file hasn’t changed and serves the cached version.
The solution is to change the asset’s URL whenever the file content changes. In WordPress, the recommended way to do this is by using the version parameter in wp_enqueue_style() and wp_enqueue_script().
?ver=1.2.3). When the version changes, the URL changes, forcing the browser to download the fresh file.
Versioning Basics with wp_enqueue_style and wp_enqueue_script
Both functions accept a $ver parameter (the fourth argument for wp_enqueue_style, and the third for wp_enqueue_script). If you don’t specify a version, WordPress uses the global $wp_version, which rarely changes for your custom assets.
Example:
wp_enqueue_style('my-theme-style', get_template_directory_uri() . '/style.css', array(), '1.0.0');
wp_enqueue_script('my-theme-script', get_template_directory_uri() . '/js/main.js', array('jquery'), '1.0.0', true);
To force updates, you need to change the version number every time you modify the file. Manually updating the version is error‑prone. That’s where automated methods like filemtime() come in.
Using filemtime() for Automatic Versioning
The filemtime() function returns the last modification timestamp of a file. You can use this timestamp as the version number. When the file changes, the timestamp updates, automatically busting the cache.
Implementation:
$css_file = get_template_directory() . '/style.css';
$css_version = filemtime($css_file);
wp_enqueue_style('my-theme-style', get_template_directory_uri() . '/style.css', array(), $css_version);
$js_file = get_template_directory() . '/js/main.js';
$js_version = filemtime($js_file);
wp_enqueue_script('my-theme-script', get_template_directory_uri() . '/js/main.js', array('jquery'), $js_version, true);
This approach is reliable and widely used. However, if you use a CDN or a caching plugin that ignores query strings, you might need additional measures (like using a version in the filename itself, but that's less common).
filemtime() on every page load, but for most sites the overhead is negligible.
Query String Versioning (Cache‑Busting)
WordPress automatically appends the version as a query string. For example: style.css?ver=1234567890. This is the simplest cache‑busting method and works with most browsers and CDNs.
Some hosting environments or caching plugins may strip query strings for performance reasons. If that happens, you may need to rename the actual file or use a filter like script_loader_src to modify the URL.
Custom filter approach:
add_filter('style_loader_src', 'my_custom_version_query', 999, 2);
function my_custom_version_query($src, $handle) {
if ($handle === 'my-theme-style') {
$src = add_query_arg('ver', filemtime(get_template_directory() . '/style.css'), $src);
}
return $src;
}
Manual Versioning (When Automation Isn’t Possible)
In some cases, you might want to control the version manually—for example, when using a version control system or when you want to force a cache update on a specific date.
You can define a constant in your theme's functions.php and increment it manually:
define('MY_THEME_VERSION', '1.0.2'); // increment when you change CSS/JS
wp_enqueue_style('my-theme-style', get_template_directory_uri() . '/style.css', array(), MY_THEME_VERSION);
wp_enqueue_script('my-theme-script', get_template_directory_uri() . '/js/main.js', array('jquery'), MY_THEME_VERSION, true);
This is simple and gives you full control, but you must remember to update the constant. Combine this with a version control commit hook for automation.
Debugging Cache Issues
When your CSS/JS still doesn’t update, try these steps:
- Clear your browser cache or use an incognito/private window.
- Check the actual URL of the enqueued asset in the browser’s dev tools (Network tab). Look at the query string—does it reflect the new version?
- Disable caching plugins temporarily to rule them out.
- Check your CDN (e.g., Cloudflare) – it might have its own cache that respects query strings or ignores them. Purge the CDN cache.
- Verify the file path in
filemtime()– ensure it points to the correct absolute path. - Use the
script_loader_srcandstyle_loader_srcfilters to debug and modify the URL. - Check server‑side caching (e.g., Varnish, Nginx fastcgi cache) – these may also cache assets.
Best Practices for CSS/JS Versioning
- Always use a version parameter – never leave it blank or rely solely on the core version.
- Use
filemtime()for automatic, foolproof versioning in development and production. - Combine and minify assets to reduce HTTP requests, but ensure the combined file also uses versioning.
- Use a build process (like Webpack or Gulp) to add a hash to filenames (e.g.,
style-1a2b3c.css) for even stronger cache‑busting. - Set far‑future expiration headers for static assets, because the versioning will bust the cache when needed.
- Test thoroughly after each update to ensure all assets load correctly.
- Consider using a cache‑busting plugin if you prefer a GUI, but understanding the code is better for custom solutions.
Frequently Asked Questions
Click a question to reveal the answer.
FreeLearning365.com@gmail.com
0 Comments
thanks for your comments!