Best way to use Google's hosted jQuery, but fall back to my hosted library on Google fail – Dev

The best answers to the question “Best way to use Google's hosted jQuery, but fall back to my hosted library on Google fail” in the category Dev.


What would be a good way to attempt to load the hosted jQuery at Google (or other Google hosted libs), but load my copy of jQuery if the Google attempt fails?

I’m not saying Google is flaky. There are cases where the Google copy is blocked (apparently in Iran, for instance).

Would I set up a timer and check for the jQuery object?

What would be the danger of both copies coming through?

Not really looking for answers like “just use the Google one” or “just use your own.” I understand those arguments. I also understand that the user is likely to have the Google version cached. I’m thinking about fallbacks for the cloud in general.

Edit: This part added…

Since Google suggests using google.load to load the ajax libraries, and it performs a callback when done, I’m wondering if that’s the key to serializing this problem.

I know it sounds a bit crazy. I’m just trying to figure out if it can be done in a reliable way or not.

Update: jQuery now hosted on Microsoft’s CDN.


The easiest and cleanest way to do this by far:

<script src=""></script>
<script>window.jQuery || document.write('<script src="path/to/your/jquery"><\/script>')</script>


You can achieve it like this:

<script src=""></script>

       window.jQuery || document.write('<script src="/path/to/your/jquery"><\/script>');

This should be in your page’s <head> and any jQuery ready event handlers should be in the <body> to avoid errors (although it’s not fool-proof!).

One more reason to not use Google-hosted jQuery is that in some countries, Google’s domain name is banned.


If you have modernizr.js embedded on your site, you can use the built-in yepnope.js to load your scripts asynchronously – among others jQuery (with fallback).

    load : '//'
    test : window.jQuery,
    nope : 'path/to/local/jquery-1.7.2.min.js',
    both : ['myscript.js', 'another-script.js'],
    complete : function () {

This loads jQuery from the Google-cdn. Afterwards it’s checked, if jQuery was loaded successfully. If not (“nope”), the local version is loaded. Also your personal scripts are loaded – the “both” indicates, that the load-process is iniated independently from the result of the test.

When all load-processes are complete, a function is executed, in the case ‘MyApp.init’.

I personally prefer this way of asynchronous script loading. And as I rely on the feature-tests provided by modernizr when building a site, I have it embedded on the site anyway. So there’s actually no overhead.


This seems to work for me:

<script type="text/javascript" src=""></script>
<script type="text/javascript">
// has the google object loaded?
if ( && {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src=""><\/script>');
window.onload = function() {
    $('#test').css({'border':'2px solid #f00'});
    <p id="test">hello jQuery</p>

The way it works is to use the google object that calling loads onto the window object. If that object is not present, we are assuming that access to Google is failing. If that is the case, we load a local copy using document.write. (I’m using my own server in this case, please use your own for testing this).

I also test for the presence of – I could also do a typeof check to see that things are objects or functions as appropriate. But I think this does the trick.

Here’s just the loading logic, since code highlighting seems to fail since I posted the whole HTML page I was testing:

if ( && {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src=""><\/script>');

Though I must say, I’m not sure that if this is a concern for your site visitors you should be fiddling with the Google AJAX Libraries API at all.

Fun fact: I tried initially to use a try..catch block for this in various versions but could not find a combination that was as clean as this. I’d be interested to see other implementations of this idea, purely as an exercise.