Sensible script enqueuing for shortcodes

If you are making a WordPress plugin which uses a shortcode, and said shortcode needs some Javascript enqueued in order to function, it may be tempting to just whack the script in the wp_enqueue_scripts hook and be done with it.

add_action( 'wp_enqueue_scripts', 'enqueue_my_script' );

function enqueue_my_script() {
wp_enqueue_script( 'script-name', plugins_url( '/js/script.js' , __FILE__ ), array(), '1.0.0', false );

Yes this works fine, and is perfectly fine during development, but as the script gets loaded site wide this can be terribly inefficient if the script is specific to your plugin.

To improve matters, you can employ some conditional tags to control where your script gets loaded. For example:

add_action( 'wp_enqueue_scripts', 'enqueue_my_script' );

function enqueue_my_script() {
if ( is_archive() || is_single() ) {
wp_enqueue_script( 'script-name', plugins_url( '/js/script.js' , __FILE__ ), array(), '1.0.0', false );

The above code would enqueue on single posts and within post archives.

For a shortcode however, this can be tricky; you know the shortcode can only be used within posts and pages, but a) thats pretty much site wide anyway and b) you don’t know if the shortcode is being used on the page you are enqueuing the script.

One way you can further optimise your enqueue would be to check the content of a post and see if it contains your code – but again, the drawback is that will most likely only work in certain situations, for example if your shortcode is intended to be used when viewing single posts only.

The sensible method

Forget conditional tags. Forget enqueuing site wide. Instead the solution is quite simple…

First, register your script early, don’t enqueue it.

add_action( 'wp_enqueue_scripts', 'register_my_script' );

function register_my_script() {
wp_register_script( 'script-name', plugins_url( '/js/script.js' , __FILE__ ), array(), '1.0.0', true );

At this point, WordPress is aware your script exists, but it won’t be loaded onto pages. Notice the ‘true’ in your wp_register_script call – this is important and tells WP that you want the script to be loaded in the footer of your page.

Next, and this is the best part, you can enqueue on demand. Now in your plugin where you render your shortcode simply add:

wp_enqueue_script( 'script-name' );

This will enqueue your previously registered script ready for output in the footer of the page.

Now you have a lazy-loaded script, and no need for fancy conditional rules – much better.

Published by Mike Jolley

I help build things at Automattic.

14 thoughts on “Sensible script enqueuing for shortcodes

  1. That’s really a sensible way out I always to enqueue all scripts at once in minified file, not it makes more sense. Wondering why didn’t I think of it before. Thanks anyway 🙂

  2. The first block of code in “The Sensible method” section, I think that add_action( ‘wp_enqueue_scripts’, ‘register_my_script’ );
    should be
    add_action( ‘wp_enqueue_scripts’, ‘enqueue_my_script’ );

    Or rename the function enqueue_my_script()
    function register_my_script()

  3. Another great reason to separately register then enqueue a script is that it can then be easily dequeued. You never know when a user or another plugin may have reason to disable or replace the script.

    1. Pretty certain you can dequeue something enqueued, not registered, as long as you do it before its output.

  4. Great tip. That was exactly what i did in my previous plugin. But what about enqueuing styles? Anyone has a solution on this?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: