Any advantage of using wp_scripts and is_IE when enqueuing scripts

To extend on @gmazzap suggestion on not using globals when you can use wp_scripts(), there is a shortcut for wp_scripts() for adding conditional comments called wp_script_add_data and likewise wp_style_add_data for conditional styles.

So the correct way to use conditionals as of WordPress 4.2 is like this:

/**
 * IE enqueue HTML5shiv with conditionals
 * @link http://tiny.cc/html5shiv
 */
function wpse_213701_enqueue_html5shiv()  {
    wp_enqueue_script( 'html5shiv',
        'https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js',
        array(),
        false,
        false
    );
    wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' );
}
add_action('wp_enqueue_scripts', 'wpse_213701_enqueue_html5shiv');

However, the example above is using HTML5shiv which is a unique situation. Since it has to be loaded in the head you could do something like this next example if you’re worried about a plugin like Roots Soil removing all the scripts from the head.


Most likely you won’t run into a situation like this though. It’s a very unstable thing to do since a lot of scripts are required to load in the head. Putting scripts in the footer should be done by setting $in_footer variable to true when enqueuing scripts. So if you do use roots or any cache plugin for that matter don’t plan on everything working exactly how you want right out of the box.

Here’s an ugly example of what you can do:

add_action( 'wp_head', 'wpse_213701_check_html5shiv', 1 );
function wpse_213701_check_html5shiv() {
    remove_action( 'wp_head', 'genesis_html5_ie_fix' );
    if ( !has_filter( 'wp_head', 'wp_enqueue_scripts' ) && !wp_script_is( 'html5shiv', 'done' ) ) {
        add_action('wp_head', 'wpse_213701_echo_html5shiv');
        wp_dequeue_script('html5shiv');
    }
}
function wpse_213701_echo_html5shiv() {
    echo '<!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><![endif]-->' . "\n";
}

This is overkill though and it still isn’t a guarantee that it will work. Over the past 4 years html5shiv has taken on many names which has caused it to be registered / enqueued with several different handles (html5, html5shiv, html5shim, themename-html5shiv, html5-ie-fix, and html5-polyfill just to name a few). Additionally, it’s often bundled with modernizr. With that in mind, if you think the above example is ridiculous, you’re just as well off adding the script to wp_head in your child theme since a plugins html5shiv handle will most likely named something else.

Update (Moving scripts to footer with this approach) :

This sparked some action on Roots/Soil Github page. Here’s probably the best way to do this ( as suggested by @grappler ) and still move scripts to the footer. A similar approach was posted on @kaiser’s blog a few years back.

function grappler_move_js_to_footer() 
    $scripts = wp_scripts();
    foreach( $scripts->registered as $script ) {
        if ( 'html5' == $script->handle ) {
            wp_script_add_data( $script->handle, 'group', 0 );
        } else {
            wp_script_add_data( $script->handle, 'group', 1 );
        }
    }
}
add_action( 'wp_enqueue_scripts', 'grappler_move_js_to_footer', 99 );

As for what Mark Kaplan suggested and what toscho mentioned here , you shouldn’t be using option 2’s $is_IE method. Apparently, if the HTTP header Vary: User-Agent doesn’t get sent, you will send the wrong output to users behind a cache causing it to break for those users. In regards to browser side detection here is a long thread of examples on how that might be done. Even client-side detection has it’s pitfalls.


At the end of the day, maybe the best answer is don’t use any of these methods and forget about legacy browsers since Microsoft has dropped support for them as of January 12.

Leave a Comment