WordPress: Loading jQuery correctly

Reducing the weight of a website’s resources has become an obsession for some of us, the practise of decreasing the time it takes for a website to load not only keeps our users happy but is known to be a factor in a site’s Google ranking and improve conversion rates.

Only a short while ago I noticed a problem in the way I was handling jQuery in WordPress. To start with I noticed jQuery was being loaded twice, and then after attempting to fix the problem some of my WordPress plugins lost their JavaScript functionality, this blog post will show you how to properly load jQuery so you can delivery a faster site and maintain WordPress script dependancies.

Note – A new version of this fix is now available.

The problem

So you’re creating a WordPress theme and want to use the latest version of jQuery, you might be inclined to put the following code in your template:

<!-- 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.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js"><\/script>')</script>

[aside]The code above has been lifted from the HTML5 Boilerplate, a popular default HTML5 template[/aside]

This is good, we’ve got a protocol relative version of jQuery from Google’s CDN and a fallback just in case. But look what happens, jQuery is loaded twice?

The first instance is in fact WordPress loading a local version of jQuery, output by the wp_head() function of which you’ll find in your header.php file.

The incorrect fix

There are couple of examples out there (here’s one) that suggest the following method of preventing WordPress loading the local version of jQuery.


This will remove jQuery from WordPress’ list of scripts and is great for stopping the local version being loaded, but it can also cause some of our WordPress plugins to lose their JavaScript functionality, Contact Form 7 is a good example of a plugin that loses it’s JavaScript, it won’t be able to submit a form using AJAX.

The reason some plugins might not work correctly using this method is because when you register a JavaScript file within WordPress you can specify dependancies that said file relies on, if that dependancy doesn’t exist (has been deregistered, for example) the dependant JavaScript file won’t be included. Look back at the last code example… see where I’m going with this?

The correct fix

Right, to correctly use a different jQuery source we need to remove the local version and introduce our new version to WordPress. We quite like the idea of using the protocol savvy, minified, Googlefied version, here’s the code, pop this in your functions.php file:

function load_jquery() {

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

        // deregister the original version of jQuery

        // discover the correct protocol to use
        if($_SERVER['HTTPS']=='on') {

        // register the Google CDN version
        wp_register_script('jquery', $protocol.'//ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js', false, '1.5.2');

        // add it back into the queue



add_action('template_redirect', 'load_jquery');

As well as the original deregister, we’re also discovering the correct protocol to use, then re-queuing jQuery so our script dependancies are satisfied. Now we should be using a decent source for our jQuery, only loading it once and our WordPress plugins can properly use jQuery again.

Note: We have to detect the protocol server side, if the script path starts with //ajax.googleapis.com WordPress will assume it’s path is part of your domain, like this http://mydomain.com/ajax.googleapis.com.


Hopefully you’ll find this solution useful, in a very un-scientific test earlier I found about half of WordPress driven blogs from people I follow on Twitter suffered from this issue of loading two versions of jQuery, hopefully with this example we’ll be able to reduce the size of our site and maintain jQuery within WordPress.

As always if you spot a mistake or think something could be don better, don’t hesitate to leave a comment below.

Note – A new version of this fix is now available.

  • Justin

    Thanks for the tip, i’ve been loading the CDN correctly, but not protocol-relative as the ‘//’ wasn’t working.

    Have you had any luck setting up a local fallback for jQuery in wordpress along the same lines?

  • If I understand you correctly Justin, WordPress will not allow a resource URL to start with ‘//’, as, unlike within the browser, there is no comprehension of protocol relativity… hopefully I’ve worded that correctly.

    That is why I check to see whether the request is HTTPS, and generate the CDN URL based on that information.

    As for a local fallback version, I haven’t actually tried yet, the problem is jQuery needs to load before any dependant scripts, however I don’t think you can interrupt the WordPress resources queue to add this code after the jQuery script but before everything that follows:

    <script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js"><\/script>')</script>

  • David Hobson

    Also, it’s worth noting that although google CDN is very reliable (even though it did go down once a while back), some countries block google.

    Good designs should always have a graceful fallback, but to be thorough, it’s worth double checking that the google version loaded, and load the local version in case. Here’s a superb discussion on stack overflow:


    PS love the site design, specifically how you used the background.

  • Another thought on top of that.

    What happens if script isn’t deregistered and enqueued properly, how big of a deal is it?

    If google’s jQuery doesn’t load, we fall back to the local version. But the only check is via js, thus we can’t enqueue the local script if google’s fails to load. My only thought is ajax, but I’m not sure if that’ll even cut it given it’s probably a bit late.

    I guess I don’t know well enough what happens if the jquery that’s loaded isn’t where the plugin thinks it is, and if what I’m describing is a legit, albeit very rare, issue.

    PS – if you had a subscribe to comments button, people like me would be more likely to come back and contribute to the conversation :-)

  • Hi David,

    Many thanks for commenting, you raise some good points.

    And I’ll put comment subscription on the to do list :-)

  • Really nice programming talents you`ve there. i`m a programmer myself but I still will need to be informed till I succeed in your skill. nice write-up!

  • LOL it’s ironic. If it loads both local and remote copy, what’s point of remote?

  • Rafael

    Thank you so much! After trying all these others solutions, yours worked perfectly. Thanks!

  • Finally, thank you. No more jQuery version conflicts.

  • William from Lagos

    Great. Just the confirmation I needed. I realized deregistering jQuery, deregistered other scripts that were dependent on it

  • ‫جواد باشتنی‬‎

    you can check this out!

    spicified correctly…
    دانلود فیلم خارجی با دوبله فارسی