In WordPress, instead of simply adding these to the header, you should use a method called enqueueing which is a standardized way of handling your assets with the added bonus of managing dependencies. Find out how to do it below using wp_enqueue_scripts.

How Enqueueing Works

There are two steps taken when enqueueing a script or a style. First you register it – tell WordPress it’s there – and then you actually enqueue it, which eventually outputs it into the header or just before the closing body tag.

The reason for having two steps has to do with modularity. Sometimes you’ll want to let WordPress know about an asset, but you may not want to use it on every page. For example: If you’re building a custom gallery shortcode that uses Javascript you only actually need to load the JS when the shortcode is used – probably not on every page.

The way to make this happen is to register the script first, and only actually enqueue it when the shortcode is shown (suggested reading: The Ultimate Guide to WordPress Shortcodes).

Enqueueing Basics With wp_enqueue_scripts

To enqueue scripts and styles in the front-end you’ll need to use the wp_enqueue_scripts hook. Within the hooked function you can use the wp_register_script(), wp_enqueue_script(), wp_register_style() and wp_enqueue_style() functions.

add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );
function my_plugin_assets() {
    wp_register_style( 'custom-gallery', plugins_url( '/css/gallery.css' , __FILE__ ) );
    wp_register_script( 'custom-gallery', plugins_url( '/js/gallery.js' , __FILE__ ) );

    wp_enqueue_style( 'custom-gallery' );
    wp_enqueue_script( 'custom-gallery' );
}

In the example above I registered and enqueued the assets within the same function, which is a bit redundant. In fact, you can use the enqueue functions to register and enqueue right away, by using the same arguments as you do in the register functions:

add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );
function my_plugin_assets() {
    wp_enqueue_style( 'custom-gallery', plugins_url( '/css/gallery.css' , __FILE__ ) );
    wp_enqueue_script( 'custom-gallery', plugins_url( '/js/gallery.js' , __FILE__ ) );
}

If I were to separate the two functions I would do so by using them in different hooks. In a real-world example we could use the wp_enqueue_scripts hook to register the assets and the shortcode’s function to enqueue them.

add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );
function my_plugin_assets() {
    wp_register_style( 'custom-gallery', plugins_url( '/css/gallery.css' , __FILE__ ) );
    wp_register_script( 'custom-gallery', plugins_url( '/js/gallery.js' , __FILE__ ) );

}

add_shortcode( 'custom_gallery', 'custom_gallery' );

function custom_gallery( $atts ){

    wp_enqueue_style( 'custom-gallery' );
    wp_enqueue_script( 'custom-gallery' );

    // Gallery code here
}

Dependency Management

WordPress’ enqueueing mechanism has built-in support for dependency management, using the third argument of both wp_register_style() and wp_register_script() functions. You can also use the enqueuing functions right away if you don’t need to separate them.

The third parameter is an array of registered scripts/styles that need to be loaded before the current asset is enqueued. Our example above would most probably rely on jQuery so let’s specify that now:

add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );
function my_plugin_assets() {
    wp_enqueue_script( 'custom-gallery', plugins_url( '/js/gallery.js' , __FILE__ ), array( 'jquery' ) );
}

We do not need to register or enqueue jQuery ourselves because it is already a part of WordPress. You can find a list of scripts and styles available in WordPress in the Codex.

If you have dependencies of your own, you will need to register them, otherwise your scripts won’t load. Here’s an example:

add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );
function my_plugin_assets() {
    wp_enqueue_script( 'custom-gallery', plugins_url( '/js/gallery.js' , __FILE__ ), array( 'jquery' ) );
    wp_enqueue_script( 'custom-gallery-lightbox', plugins_url( '/js/gallery-lightbox.js' , __FILE__ ), array( 'custom-gallery' ) );
}

Let’s assume that the first script is a gallery, the second is an extension to that which makes images open up in a lightbox. Note that even though our second script relies on jQuery, we do not need to specify this, as our first script will already load jQuery. That said, it may be a good idea to state all dependencies, just to make sure nothing can break if you forget to include a dependency.

WordPress now knows which scripts we need and can calculate which order they need to be added to the page.

Whenever you can get away with loading scripts in the footer, you should. This increases apparent page load times and can prevent your website from hanging while loading scripts, especially if they contain AJAX calls.

The enqueuing mechanism can add scripts to the footer using the fifth parameter (the fourth being an optional version number). Our example above would load the scripts in the footer if we modify it slightly.

add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );
function my_plugin_assets() {
    wp_enqueue_script( 'custom-gallery', plugins_url( '/js/gallery.js' , __FILE__ ), array( 'jquery' ), '1.0', true );
    wp_enqueue_script( 'custom-gallery-lightbox', plugins_url( '/js/gallery-lightbox.js' , __FILE__ ), array( 'custom-gallery', 'jquery' ), '1.0', true );
}

Specifying true as the fifth parameter will put scripts in the footer, using false, or omitting the parameter will load things in the header. As I mentioned before, whenever possible, load scripts in the footer.

Specifying Media For Styles

Using the style register/enqueue functions’ fifth parameter you can control the media type the script has been defined for (print, screen, handheld, etc.). By using this parameter you can restrict the loading of the styles to the particular media type which is a handy little optimization trick.

add_action( 'wp_enqueue_scripts', 'my_plugin_assets' );
function my_plugin_assets() {
    wp_register_style( 'custom-gallery-print', plugins_url( '/css/gallery.css' , __FILE__ ), array(), '1.0', 'print' );

}

For a full list of media types that can be used, take a look at the CSS specs.

Summary

Enqueueing assets is a powerful way of handling them. It gives you, and other plugin/theme makers, more control over the system as a whole and takes dependency management out of your hands.

If that weren’t enough, it is the way to add your assets, many theme marketplaces and the WordPress repository itself will not approve your work if you do not use this method.

Daniel Pataki

Hi, my name is Daniel, I'm the CTO here at Kinsta. You may know me from Smashing Magazine, WPMU Dev, Tuts+ and other WordPress/Development magazines. Aside from WordPress and PHP I spend most of my time around Node, React, GraphQL and other technologies in the Javascript space.

When not working on making the best hosting solution in the Universe I collect board games, play table football in the office, travel or play guitar and sing in a pretty bad band.