Versioning WordPress static assets keeps browsers and CDN edges from reusing an old stylesheet or script after a theme or plugin deployment. When the asset URL changes with the file change, the next request targets a new cache key instead of waiting for the previous object to expire everywhere.

The usual WordPress hook point is the version argument in wp_enqueue_style() or wp_enqueue_script(). That argument is appended to the asset URL as a query string, but the default behavior matters: if the argument is omitted or left as false, WordPress adds its own core version instead, which does not change when only a theme or plugin asset changes.

The safest version source depends on the deployment model. filemtime() is practical on a single node or during development, while a build hash or release string is more stable across multiple web heads. If the CDN cache policy ignores query strings, changing ?ver= will not create a new edge object, so versioned filenames or paths are the stronger fallback.

Steps to version WordPress static assets for CDN cache busting:

  1. Locate the theme or plugin code that enqueues the asset that changes during a deployment.
    $ rg -n "wp_enqueue_style|wp_enqueue_script" wp-content/themes wp-content/plugins
    wp-content/themes/example/functions.php:18:wp_enqueue_style(
    wp-content/themes/example/functions.php:26:wp_enqueue_script(

    Use the wp_enqueue_scripts hook for front-end assets, admin_enqueue_scripts for dashboard assets, and login_enqueue_scripts for the login screen.

  2. Replace the default or fixed version value with one that changes when the asset changes.
    wp_enqueue_style(
        'site-style',
        get_stylesheet_directory_uri() . '/assets/css/site.css',
        array(),
        filemtime( get_stylesheet_directory() . '/assets/css/site.css' )
    );

    For a plugin asset, use the matching filesystem path helper such as plugin_dir_path( __FILE__ ) with the public URL from plugins_url().

    When the asset lives in the parent theme, switch the path helpers from get_stylesheet_directory() to get_template_directory().

  3. Set an explicit build or release version when the deploy spans multiple servers or generated assets.
    wp_enqueue_script(
        'site-app',
        get_stylesheet_directory_uri() . '/assets/js/app.js',
        array(),
        'build-a1b2c3d4',
        array( 'in_footer' => true )
    );

    Replace build-a1b2c3d4 with the real build hash or release string emitted by the deployment pipeline so every node serves the same asset URL.

  4. Confirm that the CDN cache key actually varies on the chosen versioning method.

    When the CDN includes query strings in its cache key, a changed ?ver= value is enough. When the cache policy ignores query strings, rename the built file itself, such as app.a1b2c3d4.js or site.20260329.css, instead of relying on the query string alone.

  5. Deploy the enqueue-code change and the matching asset file in the same release.

    If the HTML starts referencing the new asset URL before the new file is present on every node or origin, the CDN can cache a temporary 404 or stale response for the new path.

    Use build-hash versioning instead of filemtime() when shared storage, parallel deploys, or container image rollouts can leave different nodes with different modification times for the same logical release.

  6. Inspect the rendered markup of a page that actually loads the target asset and confirm that the asset URL changed with the deployment.
    $ curl -s https://www.example.com/ | rg '/wp-content/.+(site\\.css|app\\.js)\\?ver='
    <link rel='stylesheet' id='site-style-css' href='https://www.example.com/wp-content/themes/example/assets/css/site.css?ver=1743210025' type='text/css' media='all' />
    <script src='https://www.example.com/wp-content/themes/example/assets/js/app.js?ver=build-a1b2c3d4' id='site-app-js'></script>

    Success is visible when the HTML contains the new version value and the corresponding asset request returns the expected 200 or 304.

  7. Invalidate only the stale HTML or affected asset paths when the old markup is still cached at the edge after the deployment.

    Versioned asset URLs reduce the need for repeated full-site invalidations, but a targeted invalidation is still useful when the CDN is holding the old page markup or an already cached error response.