How To Enqueue Scripts and Style Sheets on Pages With a Shortcode

Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /var/web/site/public_html/wp-content/plugins/wp-syntax/wp-syntax.php on line 383

WordPress offers an excellent mechanism for including scripts and style sheets on posts and pages. Unfortunately a lot of new plugin developers are unaware of how WordPress’ enqueuing functions work. Many plugins available in the official repository add resources to the whole website when actually they are just needed on one or two pages. In this short article you will learn how to enqueue scripts and style sheets on pages with a shortcode.

Technique 1: Calling enqueue functions from within the shortcode function

The easiest and most efficient way to enqueue scripts and style sheets on shortcode pages is to simply call the enqueue functions from within the shortcode. Here is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// First we register our resources using the init hook
function prefix_register_resources() {
	wp_register_script("prefix-script", plugins_url("js/script.js", __FILE__), array(), "1.0", false);
	wp_register_style("prefix-style", plugins_url("css/style.css", __FILE__), array(), "1.0", "all");
}
add_action( 'init', 'prefix_register_resources' );
 
// Then we define our shortcode and enqueue the resources defined above
function prefix_shortcode() {
	wp_enqueue_script("prefix-script");
	wp_enqueue_script("prefix-style");
	return "Some shortcode content";
}
add_shortcode( 'my_shortcode', 'prefix_shortcode' );

The first function registers the scripts and style sheets with the help of the init hook. Then we call the enqueuing functions in the shortcode callback. The only drawback of this method is that you can’t add items to the head section because when the shortcode callback is executed the head section has already been printed out.

Technique 2: Looking for posts with shortcodes

Another method is to check the content of each post being loaded and enqueue resources only if the shortcode is found. Here is how you can accomplish this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function prefix_enqueue($posts) {
	if ( empty($posts) || is_admin() )
		return $posts;
 
	$found = false;
	foreach ($posts as $post) {
		if ( has_shortcode($post->post_content, 'my_shortcode') ){
			$found = true;
			break;
		}
	}
 
	if ($found){
		wp_enqueue_script("prefix-script", plugins_url("js/script.js", __FILE__), array(), "1.0", false);
		wp_enqueue_style("prefix-style", plugins_url("css/style.css", __FILE__), array(), "1.0", "all");
	}
	return $posts;
}
add_action('the_posts', 'prefix_enqueue' );

This code snippet looks for shortcodes using WordPress’ own has_shortcode() function and calls wp_enqueue_script() and wp_enqueue_style() if one is found. The advantage of this method is that you can include a script or stylesheet in the head section of the page. However it also has disadvantages. For one, searching for shortcodes in the content of every post is quite inefficient. Moreover the function has_shortcode() is not available in older versions of WordPress so you might have to copy it into your code for backward compatibility.

Both of the techniques mentioned in this article have their advantages and disadvantages. Personally I prefer the former since it is faster and more intuitive. However if for some reason you have to add a script or stylesheet to the head section of your website then the second one will do the trick. Let us know if you know any other similar solutions.

Leave a reply