How to enqueue jQuery fallback – WordPress

In an HTML template I found the following two lines of code that’s loading external scripts. The first one is very familiar jQuery library from the CDN, but the second one is odd to me.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery-1.9.1.min.js"></script>')</script>

As a WordPress developer, I can enqueue the first one with wp_enqueue_script():

Read More
function scripts() {
   wp_enqueue_script( 'jquery-latest', 'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js' );
}
add_action('wp_enqueue_scripts', 'scripts');

But I’m wondering, how to do the second one?

So my question is twofold:

  1. What’s that line of code? Is that a fallback only triggered when the CDN fails?
  2. How to enqueue but hard code the second line in WordPress?

EDIT

After the answer of @RobSchmuecker I actually got the point. But with lack of experience in that way seeking the right way of execution actually, here is my code:

function scripts() {
   wp_enqueue_script( 'jquery-latest', 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js' );
   wp_localize_script( 'jquery-fallback', 'styleSheetURL', get_stylesheet_directory_uri() );
   wp_enqueue_script( 'jquery-fallback', get_template_directory_uri() . '/js/jquery-fallback.js', array( 'jquery-latest' ) );
}
add_action('wp_enqueue_scripts', 'scripts');

And I set the jquery-fallback.js in your way, only with the following line:

window.jQuery || document.write('<script src="' + styleSheetURL + '/js/jquery-1.11.1.min.js"></script>');

File hierarchy is:

/ functions.php
/ js
    / jquery-1.11.1.min.js
    / jquery-fallback.js

But I’m failing to load the jQuery from the local server.

EDIT 2

The HTML output seems correct. I speculated the jquery-fallback.js file from the browser, and it’s showing the exact file as mentioned earlier. But I changed the path to styleSheetURL + '/jquery-1.11.1.min.js.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js?ver=3.9.1"></script>
<script type="text/javascript" src="http://localhost/PROJECTDIRECTORY/wp-content/themes/MYTHEME/js/jquery-fallback.js?ver=3.9.1"></script>

But still the console is saying there are at least 4 dependent jQuery calls are missed.

Related posts

Leave a Reply

4 comments

  1. Yes it certainly looks like it is a fallback in case the CDN is not working.

    To reliably get it to work I would make a JS file with these contents:

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

    call that say fallback.js and obviously within that the src references your own copy of jQuery. Then enqueue the fallback.js file with a dependency on jquery-latest.

    To make sure you can insert the correct path you would also employ wp_localize_script http://codex.wordpress.org/Function_Reference/wp_localize_script

    <?php wp_localize_script( 'fallback', 'styleSheetURL', get_stylesheet_directory_uri() ); ?> 
    

    which would then mean you would change your fallback.js to

    window.jQuery || document.write('<script src="' + styleSheetURL + 'js/jquery-1.9.1.min.js"></script>');
    
  2. As of 4.5 there is a new function that you can use, see my detailed answer on wordpress.stackexchange here.

    The short version:

    You can use wp_scripts()->add_inline_script(), which will append a js script to an enqueued script, no questions asked, no code problems checked (there is a wrapper function wp_add_inline_script that does checks but does not permit </script> tags, even encoded).

    This is a working example

    function _enqueue_my_scripts() {
      // the normal enqueue
      wp_enqueue_script( 'jquery-cdn', 'https://code.jquery.com/jquery-3.3.1.min.js' );
      // our custom code which will check for the existance of jQuery (in this case)
      wp_scripts()->add_inline_script( 'jquery-cdn',
        "window.jQuery || document.write('<script src="".get_template_directory_uri() ."/js/jQuery.js">\x3C/script>')", 'after');
    }
    add_action('wp_enqueue_scripts', '_enqueue_my_scripts', 100);
    

    which will give you

    <script type='text/javascript' src='https://code.jquery.com/jquery-3.3.1.min.js'></script>
    <script type='text/javascript'>
    window.Swiper || document.write('<script src="http://localhost/wordpress/wp-content/themes/wp-theme/js/jQuery.js">x3C/script>')
    </script>
    

    in your HTML.

    Replace ‘window.jQuery’ and ‘/js/jQuery.js’ according to your needs but don’t touch the rest of the line as it is meant to pass through the correct line to the HTML.

  3. Per WordPress documentation, wp_localize_script “Localizes a registered script with data for a JavaScript variable.” The fallback.js script must be registered first. Rob Schmuecker got me 90% there, but the fallback didn’t work until I registered the script first, then localized the filePathURL, then enqueued the fallback.

    Also, there is no reason to create a dependency as that would cause the fallback script not to be loaded as well. Here is my final code:

    fallback.js

        window.jQuery || document.write('<script src="' + filePathURL + '/js/vendor/jquery-1.11.2.min.js"></script>');
    

    functions.php

        wp_deregister_script( 'jquery' );
        wp_enqueue_script( 'jquery',   'http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', array(), '1.11.2', true );
    
        //Fallback
        wp_register_script( 'fallback', get_template_directory_uri() .  '/js/fallback.js', array(), null, true );
        wp_localize_script( 'fallback', 'filePathURL', get_template_directory_uri() );
        wp_enqueue_script( 'fallback');
    

    Works great!

  4. In addition to the question’s 1st edit I’d suggest calling the CDN version of the enqueued script “jquery-cdn” or “jquery-latest” or similar and calling the fallback version just “jquery”. That way, no other enqueueing needs to be changed and the order of dependencies ensures that both CDN version and fallback are enqueued whenever “jquery” is required.

    Additionally, the order of calls won’t work, because, according to the docs:

    IMPORTANT! wp_localize_script() MUST be called after the script has
    been registered using wp_register_script() or wp_enqueue_script().

    So your final function would look something like this:

    function scripts() {
       wp_enqueue_script( 'jquery-latest', 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js' );
       wp_enqueue_script( 'jquery', get_template_directory_uri() . '/js/jquery-fallback.js', array( 'jquery-latest' ) );
       wp_localize_script( 'jquery', 'styleSheetURL', get_stylesheet_directory_uri() );
    }
    add_action('wp_enqueue_scripts', 'scripts');