Javascript and WordPress – The Definitive Guide

Using custom JavaScript code in a WordPress theme or plugin is, in many cases, a given. Fortunately, WordPress comes bundled with a selection of popular Javascript libraries (jQuery, Prototype and others) for use with your plugins and themes. Many users, however, simply write the `<script>` tags in the header.php file of their theme or as part of a function in their plugin that is run in the header of the theme being used. This is a potential problem area that can have you, the developer, sitting for ages looking at your code and wondering why plugin `X` isn’t working correctly when theme `Y` is active. This guide aims to provide an understanding of how to correctly enqueue Javascript in WordPress and how to avoid potential Javascript conflicts.

Okay, what are we doing here?

We’re going to enqueue the Javascript files, used by our WordPress plugin or theme, using the correct method and the wp_enqueue_script()function. We will be adding an action to the wp_print_scripts() action and, inside a function within our theme or plugin, running the wp_enqueue_script() function. We will also be including the Javascript in the administration area only, creating dependencies between our various custom Javascript files and enqueuing the scripts on only a specific page in the administration area.

How do we enqueue the Javascript?

Okay, you will need:

  1. 1 x custom function in either your theme’s functions.php file or in your plugin.
  2. 1 x selection of Javascript files required by your theme or plugin.
  3. 1 x add_action() line within your code.

Lets follow this like a recipe. The above ingredients each form part of the recipe we need to follow in order to correctly enqueue Javascript in WordPress.

1. Write a function in your theme or plugin that will run the various enqueue commands.

This function is the heart of enqueuing the JavaScripts in WordPress. It tells the system which scripts to include, what they require (if anything) and in what order to enqueue the scripts. An example of this function may look like this:
function matty_enqueue_theme_js () {
wp_enqueue_script('matty-functions', get_template_directory_uri() . 'js/functions.js', array('jquery'), '1.0', false);
} // End matty_enqueue_theme_js()

Okay. Lets run through this function and work out what it does.

For each Javascript file you wish to include, add another wp_enqueue_script() line to the function. This line reads as follows:

The name by which I would like to refer to this JavaScript file is `matty-functions`. It is located at get_template_directory_uri() . ‘js/functions.js’ *, requires jQuery to run and has a version number of 1.0. The `false` at the end denotes whether or not the script is to be loaded in the footer of the theme (on wp_footer()). If false, the script will load in wp_head() of the current theme.

Each parameter can be explained as follows:

$handle – A lowercase text string, no spaces, that is the “identifier” of the JavaScript file being loaded on that line. Can be used if one of your files requires another of your files in order to run.

$src – The full URL path to the Javascript file being loaded.

$deps – Does your script require anything to run? It could require a specific library (for example, jQuery) or another of your Javascript files being loaded in (referred to by its $handle).

$ver – The version number of the script being loaded. This is an optional parameter.

$in_footer – Should the script be loaded in the footer or in the header? If set to false, the script will load in the header. This is an optional parameter that defaults to `false`.

And hey presto! We’ve got a function that we can tell to include all our JavaScripts!

Run the function when the WordPress wp_print_scripts() action occurs.

No sweat. We’re going to run the above function on the WordPress wp_head()action (when the system initialises). This is how we do it: add_action('wp_print_scripts', 'matty_enqueue_theme_js', 1);

Explaination? Okay.

When the WordPress wp_print_scripts() function runs, add the `matty_enqueue_theme_js` function to the list of functions to run. Give it a priority setting of 1 (this can be used to control which functions execute before others).

Easy, right?

What JavaScript libraries are already bundled with WordPress?

In a word; loads. Here’s a comprehensive list of Javascript libraries bundled with WordPress. Try to stick to one library, as it will greatly minimize potential conflicts between your scripts. Where possible, be sure to use the bundled version of the script your code requires, as it will minimize load times and generally be a lot easier to work with your scripts (unless the version you require is not yet bundled with WordPress… *cough* jQuery 1.4 *cough*.).

I only want the Javascript in the WordPress aministration area. How do I do that?

No sweat. Simply run the following script instead of the above add_action():

add_action('admin_print_scripts', 'matty_enqueue_theme_js');

To include the Javascript on only one particular administration page, run something like the following:

add_action('admin_print_scripts-widgets.php', 'matty_enqueue_theme_js');

The above line will enqueue the JavaScript only on the widgets screen of the administration area.

One of my scripts relies on another. What do I do?

Remember that `$handle` parameter we discussed earlier? Lets use it.

When one script relies on another script (note: not a bundled library but another custom Javascript file), the ‘handle’ parameter is used in the `$deps` to let the script know that another script is required. Lets take a look at our function again:

function matty_enqueue_theme_js () {
wp_enqueue_script('matty-some-cool-code', get_template_directory_uri() . 'js/some-cool-code.js', array('jquery'), '1.0', false);
wp_enqueue_script('matty-functions', get_template_directory_uri() . 'js/functions.js', array('jquery', 'matty-some-cool-code'), '1.0', false);
} // End matty_enqueue_theme_js()

See what we did there? We added the handle of the first line to the dependencies array of the second line. Therefore, ‘matty-some-cool-code’ requires jQuery ** to run, and ‘matty-functions’ requires both jQuery and ‘matty-some-cool-code’ in order to run. Please note that, because I have specified that my scripts require jQuery, there is no need to load the jQuery library itself on it’s own line.

Right. Lets sum it up.

What did we discuss here today? We learned how to correctly enqueue Javascript files in WordPress, how to create dependencies between files and how to load Javascript libraries that come bundled with WordPress.

And all the code we discussed above:
function matty_enqueue_theme_js () {
wp_enqueue_script('matty-some-cool-code', get_template_directory_uri() . 'js/some-cool-code.js', array('jquery'), '1.0', false);
wp_enqueue_script('matty-functions', get_template_directory_uri() . 'js/functions.js', array('jquery', 'matty-some-cool-code'), '1.0', false);
} // End matty_enqueue_theme_js()

add_action( 'wp_print_scripts', 'matty_enqueue_theme_js', 1 );
I hope this post is found useful. If you have any queries, please post them in the comments.

* get_template_directory_uri() should be changed to get_stylesheet_directory_uri() if the JavaScript file is within a child theme.

** Notice how jQuery is required by both JavaScripts but is only loaded once in your code? This is why we use the wp_enqueue_script() action… to avoid a) multiple versions or instances of a script being included and b) to avoid script conflicts because of these load issues.

18 responses to “Javascript and WordPress – The Definitive Guide”

    • Hey Chris,
      Thanks man. Glad you like. 🙂

      I’ve experienced Javascript conflicts, once or twice, where the issue ultimately stemmed from this very thing- incorrect inclusion of the Javascript. Thought others
      may have had/be having similar issues and that this could help.

      Always great to hear from you man. 🙂

      Cheers,
      Matt.

  1. Hey Matt,

    Ye, I’ve hit issues quite a few times and as much as I search the Internet, I’m yet to find an article that really gets down to the bottom of it, so I’m well impressed to see this one, thank you for sharing it!

    Chat to you soon bro.

    • Hey Brendon,
      Thanks man. 🙂

      It seems like one of those things that can get in the way really easily if it isn’t handled correctly. 😛

      Glad the post is useful man. 🙂

      Cheers,
      Matt.

  2. Hi Matt,

    Great write up about WordPress and JavaScript! This post is really useful, especially when most of the themes I bought ended up with javascript spilling all over the place. Those developers really need to learn how to properly organize js and css files.

    If you could add a syntax highlighter to your blog post, that would be great!

    I’m following you on Twitter.

    • Hi Gary,
      Thanks so much for your kind words. I really appreciate it and am glad you found this post to be useful.

      I’m currently in the process of redesigning and recoding this blog. I will be adding features to enhance the code visibility and will look into adding a syntax highlighter. Thanks for the note. 🙂

      Cheers,
      Matty.

    • Thanks. 🙂

      Yeah, I do wrap my code snippets in CODE tags. I’ll be highlighting them more in my redesign (coming soon) as well as looking into adding a syntax highlighter to make longer snippets easier to read.

      Thanks again for your comment. 🙂

  3. Hi Matt,

    Wonder if you could help… I’ve tried your technique with the Coda-Slider. I’ve implemented it in my template file using this:

    <script type="text/javascript" src="/scripts/jquery-1.3.2.min.js”>
    <script type="text/javascript" src="/scripts/jquery.easing.1.3.js”>
    <script type="text/javascript" src="/scripts/jquery.coda-slider-2.0.js”>

    $().ready(function() {
    $(‘#coda-slider-1’).codaSlider();
    $(‘#coda-slider-2’).codaSlider({
    dynamicArrows: false,
    dynamicTabs: false,
    autoSlide: true,
    autoSlideInterval: 4000,
    autoSlideStopWhenClicked: true
    });
    $(‘#coda-slider-3’).codaSlider();
    $(‘#coda-slider-4’).codaSlider();
    $(‘#coda-slider-5’).codaSlider({
    dynamicArrows: false,
    dynamicTabs: false
    });
    $(‘#coda-slider-6’).codaSlider({
    crossLinking: false,
    firstPanelToLoad: 3
    });
    $(‘#coda-slider-7’).codaSlider({
    autoHeightEaseDuration: 300,
    autoHeightEaseFunction: “easeInOutExpo”,
    slideEaseDuration: 300,
    slideEaseFunction: “easeInOutExpo”
    });
    $(‘#coda-slider-8’).codaSlider({
    autoHeightEaseDuration: 2500,
    autoHeightEaseFunction: “easeInOutElastic”,
    slideEaseDuration: 2500,
    slideEaseFunction: “easeInOutElastic”
    });
    $(‘#coda-slider-9’).codaSlider({
    dynamicArrows: false
    });
    });

    And works fine. However, that’s not the proper way to do it, so using your tutorial I wrote this code:

    function wm_enqueue_theme_js () {
    wp_enqueue_script(‘easing’, TEMPLATE_URL . ‘scripts/jquery.easing.1.3.js’, array(‘jquery’), ‘1.0’, false);
    wp_enqueue_script(‘coda-slider’, TEMPLATE_URL . ‘scripts/jquery.coda-slider-2.0.js’, array(‘jquery’, ‘easing’), ‘1.0’, false);
    } // End wm_enqueue_theme_js()

    add_action(‘init’, ‘wm_enqueue_theme_js’);

    And added into my functions file. But it doesn’t work! Any ideas of why? Thanks!

    • Hi Wagner,
      Thanks for checking in. 🙂

      Regarding your query, I have a few ideas:

      1. Your code to create the slider itself needs to be in a JavaScript file, that would also need to be enqueued. I’d recommend creating a generic functions.js file, stored in your “scripts” folder, containing the code to setup the Coda slider. You would then need to add another enqueue below the line entitled “coda-slider”, to enqueue your setup script for the slider.

      2. Do you have “TEMPLATE_URL” defined? If not, add this to your functions.php file (preferably at the top):

      define( 'TEMPLATE_URL', trailingslashit( get_stylesheet_directory_uri() ) );

      This sets TEMPLATE_URL equal to your theme’s folder and enables the correct direct link to each JavaScript file.

      3. Change the action from running on init() to wp_head(). I have found this to work better and have amended the blog post to reflect this.

      I hope this helps, Wagner. Please let me know if you require any further assistance with this. 🙂

      Cheers,
      Matt.

  4. @Wagner – Hey mate, I know this is late, but here it goes anyway… I went through this one with our themes, with this technique it’s best to use jQuery instead of $ so instead of saying:

    $(“selector”)

    Use

    jQuery(“selector”)

    Or you could also say jQuery().ready(function($) {}; if you want to keep using your $ signs…

    Cheers

  5. I am having difficulty with this and hoping someone can answer. How do I enqueue a script without a version #? Even if I leave it off, WordPress automatically adds ?ver=3.0 to it… and with the version # on the URL, the script will not load.
    Any help would be appreciated.

    • Hi Ed,
      As per our correspondence, after looking through the code provided, I believe this to bea case of either the file not being pointed to correctly (ie: the path to the JavaScript file is incorrect) or a JavaScript conflict situation (the script provided looks to rely on the Prototype framework, which would need to be enqueued as well).

      I would recommend getting a single script to enqueue correctly and, from there, enqueuing one script at a time in order to isolate the JavaScript conflict.

      All the best,
      Matty.

  6. Very Well Done! This is always the kind of thing that stumps me. I moved from non-Wordpress to WordPress and things just weren’t working right. I was able to get my function file setup and you kept me from pulling all of my hair out – hooray! Thanks so much for the step by step!

  7. Alright, almost all of this makes sense to me, except for one thing. Where do i put it? I have the functions written out in one of my pages, but I have a sneaking suspicion that that is the wrong place. I only need these js scripts on one page for an electronic signature form, is there any way to embed the scripts on to only one page without editing the theme/plugin completely?

    I guess what I’m asking is, is there any way to use javascript inline like you can if you were coding it in notepad?

Leave a Reply

Your email address will not be published.

%d bloggers like this: