WordPress: Loading jQuery correctly, version 2

19th October 2011

A few months ago I posted a bit of code to properly load jQuery within WordPress, the original issue (which existed on 50% of WordPress sites I looked at that day) was jQuery being loaded twice. This issue would cause extra weight to download for the user, but most of the solutions would remove jQuery from WordPress’ resource queue without putting something back to satisfy other scripts that depend on jQuery.

Since my first version I’ve further improved the jQuery / WordPress fix, ironing out a few issues I found making this a simper and less restrictive fix, in this post I address these issues and demonstrate an improved method of loading jQuery into your WordPress theme.

Issues with the previous version

  • Generating protocol relative URLs in PHP is a bit of a pain
  • Difficult to provide fallback jQuery file
  • Too much emphasise on functions file instead of theme file

How do we solve these issues?

Easy, go back to loading jQuery in your themes footer.php file, load it how you used to in the good old days… just like the example given in the HTML5 boilerplate:

<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.4.min.js"><\/script>')</script>

We still need to register jQuery with WordPress, so my first thought was to load an empty ‘dummy’ js file, however WordPress doesn’t actually need to load a file to register jQuery as an available dependancy. With that in mind look here’s the improved fix:

function load_jquery() {

    // only use this method is we're not in wp-admin
    if ( ! is_admin() ) {

        // deregister the original version of jQuery
        wp_deregister_script('jquery');

        // register it again, this time with no file path
        wp_register_script('jquery', '', FALSE, '1.6.4');

        // add it back into the queue
        wp_enqueue_script('jquery');

    }

}

add_action('template_redirect', 'load_jquery');

Notice we’ve deregistered the original version, registered a new version (which just so happens to have no file associated with it), then placed it back in the queue. Now any other JavaScript files that depend on jQuery will load, as WordPress recognises the dependancy (jQuery) has been set. I also figured we’d need to keep the version number in there just in case another script references a specific version dependency.

A good example of a WordPress plugin that has JavaScript files that depend on jQuery is Contact Form 7, of which loses it’s ability to submit using AJAX is jQuery isn’t in WordPress’ resources queue.

With this new fix you can load jQuery however you like in your theme, thus kicking the arse of all of the issues I raised at the start of the post! The improvement from the original version seems pretty good although I haven’t been running for that long.

As always comments are welcome, especially if you spot an issue or think this can be further improved.

  • http://luckykind.com Danny

    Great read! :)

    Curious as to why the version is different in the register script VS the ones from Google’s CDN’s jQuery? Is this a big deal? Thx!

  • http://beneverard.co.uk Ben Everard

    I fail at copy and paste :D

    Cheers Danny

  • http://www.squareonemd.co.uk Elliott

    This looks a lot like Chris Coyiers original script http://css-tricks.com/snippets/wordpress/include-jquery-in-wordpress-theme/

  • http://beneverard.co.uk Ben Everard

    Hi Elliott, as I discovered in V1 of this fix this makes it a little difficult to load protocol relative versions of jQuery, and makes it slightly (but not massively) more of a pain to load a local version of jQuery if the CDN version isn’t available.

  • http://www.squareonemd.co.uk Elliott

    Google’s CDN is pretty robust and reliable though – wouldn’t you agree?

  • http://beneverard.co.uk Ben Everard

    Indeed I would, but there are countries where Google is blocked, or on the slim the cleaner has unplugged the server at Google to power their hoover ;-)

  • Aaron

    Exactly what I was looking for! Thanks for sharing.

  • David Hobson

    Nicely done!

    I forget who mentioned it, but with this link as the source, it’ll always grab the latest jQuery version. I personally might be a bit tentative doing this on a client’s site as several years down the road, something could get depreciated, but on my sites, and the snippet I keep to copy in, it’s nice:
    ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js

    I also have a habbit of checking I’m on a localhost or not. If I’m at a coffee shop and am getting poor reception, the responsiveness of the local copy is always appreciated.

    Keep the registering scripts function the same, and for readability wrap the script includes in an if/else.

    Or for super concise:
    if($_SERVER[‘HTTP_HOST’] !== ‘localhost’){
    echo ”;
    }
    echo ‘window.jQuery || document.write(\’\’)';

    If localhost, jQuery will always be false and load the local copy.
    (I haven’t had a chance to double check and test it, but I can’t imagine how it would go wrong.)

  • David Hobson

    PS – Admin – can you edit my comment? If it’s on a localhost, all of this can be bypassed as wp, a plugin, or something should have loaded the local copy elsewhere. Thus just wrap the if localhost around the add_action()

    Thanks!

  • http://youtube.com/izvarzone AntoxaGray

    Should I hardcode cdn and backup links into header.php?

  • http://www.infinite-eye.com Luke

    Hi thanks for this post – very helpful as I was having horrible script conflicts and this was one reason!

    Can you explain why you use the template_redirect hook for this function ? Is that definitely the best place to put the de-register call?

    It’s a bit of olden days hangover this enqueue script JQuery in WordPress I feel. They have done wonders with the rest however, so I am not grumbling.

    nice web design on your CMS by the way, very slick!

    Luke

  • http://tpalazzone.com John

    Thanks for this where do i need to put the second part of code?

  • http://beneverard.co.uk Ben Everard

    Hi John, the load_jquery() function can go in your funcitons.php file.

  • LM

    I quote Luke’s question: “Can you explain why you use the template_redirect hook for this function ? Is that definitely the best place to put the de-register call? “

  • http://beneverard.co.uk Ben Everard

    Whoops, sorry about not replying to that part.

    If I’m 100% honest the template_redirect hook was listed from the very first example of this fix, it worked so I left it at that.

    I’ll have a look to either justify it or find a better hook to use, unless anyone can suggest a better method.

  • http://beneverard.co.uk Ben Everard

    Right, the blurb about template_redirect:

    Runs before the determination of the template file to be used to display the requested page.

    Each request must be serviced with a template file (index.php, front-page.php, single.php etc), this hook is called before figuring out what template to use… thus it should always happen before the the output is generated and should only happen once.

    That’s my justification for using that hook, however as suggested if anyone can think of a better hook to improve this code please suggest one.

    Cheers :-)

  • http://www.patrickrauland.com Patrick Rauland

    Just what I was looking for. :)

  • http://www.zealous.co Guy Armitage

    I love you and I want you babies! You solved my JQuery troubles! Pints on me next time you’re in London

  • http://kelvincastelino.blogspot.com/ Kelvin Castelino

    What if one plugin needs a different old version of JS, and with new one it doesnt work, but the other plugin will only work with new one! But having both causes it clash, and which loads first, works, which loads later doest work! What to do at that juncture?

    • http://twitter.com/ilmv Ben Everard

      You can use whatever version of jQuery you desire, want to use an older one because a plugin still requires it, fair enough. If you require two different versions of jQuery then you have a decision to make, because in my opinion you should never have more than one version loading.

      This method will only load one version, in this instance it’s version 1.6.4 from Google’s CDN.

      Thanks for your comment :-)

      • http://kelvincastelino.blogspot.com/ Kelvin Castelino

        But the point is I want both the plugin’s to work, or edit the plugin’s myself, but then everytime it gets updated, I will have to re-modify them! So how do I excatly get along this problem?

        • http://twitter.com/ilmv Ben Everard

          Sorry Kelvin, I don’t understand what you’re problem is. Are you referring to jQuery plugins or WordPress plugins?

          • http://kelvincastelino.blogspot.com/ Kelvin Castelino

            Referring the WordPress Plugins which use jQuery.

          • http://twitter.com/ilmv Ben Everard

            Sorry for the delay Kelvin, Xmas got in the way.

            “What if one plugin needs a different old version of JS, and with new one it doesnt work, but the other plugin will only work with new one!”

            You’d still have a problem if you included jQuery manually (e.g. not via WordPress). With that in mind you would need to amend the plugin or not use it at all.

          • http://kelvincastelino.blogspot.com/ Kelvin Castelino

            Hmm then that wouldnt serve the purpose, coz when a site is delivered for the client, with an existing plugin for one purpose, and now he needs something new, which I would have to use another plugin, but there is a conflict, and the customer is not ready to give away with the old plugin, coz one he’s happy with it to use it and for its performance. So what do you suggest to do then?

          • http://twitter.com/ilmv Ben Everard

            Kelvin, this issue would exist even before you used this code, if you’ve got two plugins that need two different versions of jQuery (because they both won’t run on the same version) then you (or your client) has issues outside of WordPress. You might be able to load two versions of jQuery… but that’s certainly outside of normal scope.

            Ask on Stack Overflow if you’re continuing to have issues, I think that’ll be your best bet.

          • jquery rat

            hi, i have a question similar to your’s and i’d like to know what you did about your issue. i need jquery for a plugin that I’m making, and I’m completely confused with all this stuff like( USE GOOGLE LIBRARIES PLUGIN, Dont use google libraries cause they are banned in china, use google libraries cause ppl have em cached, dont use google libraries because some plugins need an older version than the one i’m gonna queue after deregistering native jquery) I would really like to ask anyone out there if they have any idea on a final solution to this mess. Every solution to this jquery issue comes with its own caveats. Finally i wonder whether the best way is to simply use jquery from google, without deregistering the root copy, because i just opened up the console on a few random news websites and noticed nearly half of em loading two copies of jquery – one from google and one native.

  • http://createopen.com/ Dave Hulbert

    WordPress 3.5 now lets you register scripts with protocol-relative URLs: http://core.trac.wordpress.org/ticket/16560

    • http://twitter.com/ilmv Ben Everard

      Ah, not that will come in handy. Thanks Dave