How to Add Versioning to Enqueued Assets (Cache Busting) in WordPress

December 13, 2025
How to Add Versioning to Enqueued Assets (Cache Busting) in WordPress

Loading CSS and JavaScript correctly is essential for WordPress performance, compatibility, and maintainability. Hardcoding <link> or <script> tags directly into templates often causes conflicts, duplicate loading, and cache issues.

This guide explains the proper way to enqueue CSS and JavaScript in WordPress, including dependencies, conditional loading, versioning, and performance best practices.


Why You Should Use wp_enqueue_style() and wp_enqueue_script()

WordPress provides a built-in asset management system. Using it correctly allows WordPress to:

  • Prevent duplicate loading of the same file
  • Handle dependencies automatically
  • Control load order
  • Append cache-busting versions
  • Allow plugins and themes to interact safely

Never manually echo CSS or JS tags in header.php or footer.php.


Basic Structure: Where to Put the Code

Add enqueue logic in one of the following places:

  • Child theme functions.php
  • A dedicated include file (recommended), e.g. /inc/enqueue.php
  • A custom plugin

Then hook into wp_enqueue_scripts.


Enqueue a CSS File

add_action( 'wp_enqueue_scripts', function() {

  wp_enqueue_style(
    'my-theme-style',
    get_stylesheet_directory_uri() . '/assets/css/style.css',
    array(),                // Dependencies
    '1.0.0',                // Version
    'all'                   // Media
  );

} );

Parameters Explained

  • Handle: Unique ID (my-theme-style)
  • Source: File URL
  • Dependencies: Other styles that must load first
  • Version: Used for cache busting
  • Media: Usually all or screen

Enqueue a JavaScript File

add_action( 'wp_enqueue_scripts', function() {

  wp_enqueue_script(
    'my-theme-script',
    get_stylesheet_directory_uri() . '/assets/js/main.js',
    array( 'jquery' ), // Dependencies
    '1.0.0',
    true               // Load in footer
  );

} );

Footer Loading Matters

Setting the last parameter to true loads the script just before </body>, which improves perceived performance and avoids render blocking.


Use Dependencies Correctly

WordPress ships with registered scripts such as:

  • jquery
  • jquery-core
  • wp-util
  • wp-i18n

Example: enqueue a script that depends on WordPress’s bundled jQuery.

wp_enqueue_script(
  'custom-slider',
  get_stylesheet_directory_uri() . '/assets/js/slider.js',
  array( 'jquery' ),
  '1.2.0',
  true
);

This ensures jQuery loads before your script.


Conditional Loading (Recommended)

Loading assets everywhere hurts performance. Load them only where needed.

Load CSS Only on a Specific Page

add_action( 'wp_enqueue_scripts', function() {

  if ( is_page( 'contact' ) ) {
    wp_enqueue_style(
      'contact-style',
      get_stylesheet_directory_uri() . '/assets/css/contact.css',
      array(),
      '1.0.0'
    );
  }

} );

Load JS Only on Single Posts

add_action( 'wp_enqueue_scripts', function() {

  if ( is_single() ) {
    wp_enqueue_script(
      'single-post-js',
      get_stylesheet_directory_uri() . '/assets/js/single.js',
      array(),
      '1.0.0',
      true
    );
  }

} );

Enqueue Scripts for the Admin Area

Use a different hook for admin pages.

add_action( 'admin_enqueue_scripts', function( $hook ) {

  if ( $hook !== 'post.php' && $hook !== 'post-new.php' ) {
    return;
  }

  wp_enqueue_style(
    'admin-editor-style',
    get_stylesheet_directory_uri() . '/assets/css/admin.css',
    array(),
    '1.0.0'
  );

} );

This avoids loading admin assets globally.


Pass PHP Data to JavaScript Safely

Never inline PHP variables directly into JS files. Use wp_localize_script().

wp_enqueue_script(
  'my-script',
  get_stylesheet_directory_uri() . '/assets/js/main.js',
  array(),
  '1.0.0',
  true
);

wp_localize_script(
  'my-script',
  'myData',
  array(
    'ajaxUrl' => admin_url( 'admin-ajax.php' ),
    'nonce'   => wp_create_nonce( 'my_nonce' ),
  )
);

Then access it in JavaScript:

console.log(myData.ajaxUrl);

Versioning and Cache Busting

Browsers aggressively cache assets. Use versioning wisely.

Manual Version

'1.0.3'

File Modification Time (Automatic)

$file = get_stylesheet_directory() . '/assets/css/style.css';

wp_enqueue_style(
  'theme-style',
  get_stylesheet_directory_uri() . '/assets/css/style.css',
  array(),
  filemtime( $file )
);

This forces browsers to reload the file when it changes.


Dequeue or Deregister Unused Assets

Some plugins load CSS/JS everywhere. You can safely remove them when not needed.

add_action( 'wp_enqueue_scripts', function() {

  if ( ! is_page( 'shop' ) ) {
    wp_dequeue_style( 'plugin-style-handle' );
    wp_dequeue_script( 'plugin-script-handle' );
  }

}, 100 );

Use tools like Query Monitor to find asset handles.


Common Mistakes to Avoid

  • Hardcoding <script> tags in templates
  • Loading assets globally “just in case”
  • Using the same handle twice
  • Forgetting dependencies
  • Inlining sensitive data into JS files

Recommended Best Practices

  • One responsibility per file (no giant JS bundles unless needed)
  • Conditional loading by page or post type
  • Footer loading for JS
  • Automatic versioning with filemtime()
  • Use Code Snippets or a custom plugin for enqueue logic

Conclusion

Properly enqueuing CSS and JavaScript is foundational to building fast, stable, and future-proof WordPress sites. By using WordPress’s enqueue system, you avoid conflicts, improve performance, and make your code easier to maintain.

Key takeaway:
Always enqueue → Load conditionally → Manage dependencies → Version your files → Never hardcode assets.

Mastering this pattern will immediately improve your WordPress development workflow.

Avatar

Written by

satoshi

I’ve been building and customizing WordPress themes for over 10 years. In my free time, you’ll probably find me enjoying a good football match.