Independent Editorial DeskWordPress Releases, Builds, and Operations
Back to Archive
Implementation Notes

WordPress wp_enqueue_script Example: Load Assets Safely

A production-focused wp_enqueue_script guide for loading CSS and JavaScript with dependencies, versioning, defer strategy, and conditional loading.

Published

April 16, 2026

Reading Time

1 min read

Updated

April 16, 2026

Abstract network waterfall and asset loading bars representing WordPress script enqueue performance.
Build PatternImplementation Notes

Implementation Notes

Extension points, code paths, and implementation choices that should survive contact with production.

Best For

WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.

Primary Topics

Implementation Notes

Editorial Focus

Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on April 16, 2026.

Full Report

Last reviewed: April 16, 2026

Many WordPress performance and plugin bugs start with the same shortcut: adding scripts directly into a template or pasting <script> tags into the footer. It works once, then breaks dependency order, cache invalidation, conditional loading, CSP rules, or frontend performance.

This guide gives a practical wp_enqueue_script() and wp_enqueue_style() example for themes and plugins. It focuses on dependencies, versioning, defer strategy, conditional loading, and the checks that keep assets from becoming a hidden production problem.

Who this is for

This article is for WordPress developers who need to load JavaScript and CSS safely from a theme or plugin. It is also useful for operators reviewing slow sites where every plugin appears to load assets on every page regardless of whether the feature is used.

Why this topic keeps getting searched

The common searches are practical: “wp_enqueue_script example”, “enqueue script in WordPress plugin”, “load script only on one page”, and “add defer to WordPress script”. Those queries all point to the same operational need: load the right asset, in the right order, on the right page, without blocking rendering more than necessary.

Theme example: enqueue a main stylesheet and script

In a theme, enqueue public assets from functions.php. Avoid hardcoded script tags in templates unless there is a very specific reason.

add_action( 'wp_enqueue_scripts', 'vulnwp_theme_assets' );

function vulnwp_theme_assets() {
	$theme_version = wp_get_theme()->get( 'Version' );

	wp_enqueue_style(
		'vulnwp-theme',
		get_stylesheet_uri(),
		array(),
		$theme_version
	);

	wp_enqueue_script(
		'vulnwp-theme',
		get_template_directory_uri() . '/assets/js/theme.js',
		array(),
		$theme_version,
		array(
			'in_footer' => true,
			'strategy'  => 'defer',
		)
	);
}

The important details are the handle, source URL, dependencies, version, and loading arguments. The handle is the unique identifier WordPress uses to manage dependencies and avoid duplicate loads.

Plugin example: load assets only when needed

A plugin should not load frontend assets globally unless the feature appears globally. The example below loads a small calculator script only on pages that contain a specific shortcode.

add_action( 'wp_enqueue_scripts', 'vulnwp_calculator_assets' );

function vulnwp_calculator_assets() {
	if ( ! is_singular() ) {
		return;
	}

	$post = get_post();

	if ( ! $post || ! has_shortcode( $post->post_content, 'vulnwp_calculator' ) ) {
		return;
	}

	wp_enqueue_style(
		'vulnwp-calculator',
		plugin_dir_url( __FILE__ ) . 'assets/calculator.css',
		array(),
		'1.0.0'
	);

	wp_enqueue_script(
		'vulnwp-calculator',
		plugin_dir_url( __FILE__ ) . 'assets/calculator.js',
		array(),
		'1.0.0',
		array(
			'in_footer' => true,
			'strategy'  => 'defer',
		)
	);
}

This pattern is not perfect for every site, but it is much better than loading the asset on every request. If a feature appears in blocks, widgets, templates, or archives, adapt the condition to match the real rendering path.

Dependencies and versioning

Dependencies tell WordPress which assets must load before another asset. If your script depends on jQuery, declare it instead of hoping the active theme already loaded it.

wp_enqueue_script(
	'vulnwp-legacy-widget',
	plugin_dir_url( __FILE__ ) . 'assets/legacy-widget.js',
	array( 'jquery' ),
	'1.2.3',
	array(
		'in_footer' => true,
	)
);

Versioning controls cache invalidation. In a plugin, a fixed plugin version is usually fine. During active development, some teams use filemtime(), but avoid doing expensive filesystem work unnecessarily on high-traffic production paths.

Use defer carefully

Modern WordPress supports a loading strategy argument for scripts, including defer and async. Prefer defer for many theme and UI scripts because it preserves execution order while allowing parsing to continue. Use async only when the script is truly independent.

Do not add defer blindly to every script. If a script writes directly to the document, depends on inline data, or expects another script to be complete immediately, test it carefully.

Passing data to scripts

For small configuration data, use wp_add_inline_script() after the script is registered or enqueued. Avoid building JavaScript strings with raw unescaped values.

wp_enqueue_script(
	'vulnwp-dashboard',
	plugin_dir_url( __FILE__ ) . 'assets/dashboard.js',
	array(),
	'1.0.0',
	array( 'in_footer' => true )
);

wp_add_inline_script(
	'vulnwp-dashboard',
	'window.vulnwpDashboard = ' . wp_json_encode(
		array(
			'apiRoot' => esc_url_raw( rest_url( 'vulnwp/v1/' ) ),
			'nonce'   => wp_create_nonce( 'wp_rest' ),
		)
	) . ';',
	'before'
);

This is especially relevant for REST-powered features. Pair it with a real nonce and capability model, not just frontend hiding.

Production checklist

  • Use wp_enqueue_scripts for frontend assets.
  • Use unique, prefixed handles.
  • Declare dependencies explicitly.
  • Use stable versioning so cache invalidation is predictable.
  • Load assets conditionally when the feature is not global.
  • Use defer only after testing dependencies and execution order.
  • Keep inline configuration small and JSON-encoded.
  • Review PageSpeed results after large plugin or theme changes.

Common mistakes

  • Hardcoding script tags in templates. WordPress cannot manage dependencies or duplicates.
  • Loading plugin assets on every page. This increases payload and can hurt Core Web Vitals.
  • Using no version or a random version. Cache behavior becomes hard to reason about.
  • Adding async to dependent scripts. Execution order can break.
  • Passing sensitive data to JavaScript. Anything in the page source is public to the browser.

How this connects to performance work

Asset loading is one of the first areas to inspect when a WordPress site has poor Lighthouse or PageSpeed scores. It is also a common source of regressions after plugin updates. If your production rollout includes asset changes, use this guide with our WordPress update rollout checklist.

How to debug what actually loaded

Do not stop at code review. Open the page and inspect the final HTML and network waterfall. Confirm that the asset appears only where expected, that duplicate libraries are not being loaded by multiple plugins, and that the response uses a cacheable URL with a stable version. If a script is marked defer, test the user interaction that depends on it instead of assuming the attribute is harmless.

# Look for your handle output in the rendered HTML.
curl -s https://example.com/sample-page/ | grep -i "vulnwp-calculator"

# Compare a page that should load the feature with one that should not.
curl -s https://example.com/ | grep -i "vulnwp-calculator"

In the browser, check DevTools for 404 responses, blocked mixed-content requests, duplicate jQuery loads, large uncompressed assets, and scripts that block the main thread. On WordPress sites with many plugins, the biggest performance win is often not a clever optimization. It is preventing irrelevant assets from loading on unrelated pages.

Admin assets are a separate path

Use admin_enqueue_scripts for dashboard screens and check the $hook value before loading admin JavaScript globally. A settings-page helper script does not need to run on every post edit screen, media screen, and plugin page. This keeps the admin area cleaner and reduces conflicts with other plugins.

References and further reading

Popular Guides

Popular WordPress guides to read next.

These articles connect recurring production concerns: implementation details, updates, troubleshooting, recovery paths, and operational cleanup.

Continue Reading

More from the archive.

Diagnostic dashboard scene representing a WordPress Site Health review before major updates.
01Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Site Health Check Before Major Updates: What to Review First

A pre-update WordPress Site Health checklist covering loopbacks, connectivity, debug settings, and environment readiness.

Structured data and route review scene representing permalink validation after a WordPress migration.
02Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Permalink Checklist After Migration: Catch URL Problems Early

A post-migration WordPress permalink checklist for checking rewrite rules, post URLs, archives, and redirect noise.

Technical media workspace representing image preparation and optimization before upload to WordPress.
03Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Image Optimization Checklist: What to Fix Before Upload

A practical WordPress image optimization checklist covering dimensions, compression, formats, and Media settings before upload.