21

I have this in my functions.php file and I can't get jQuery to load in the footer. The includes file loads in the footer fine, though. What else do I need to do?

function starter_scripts() {
    wp_enqueue_style( 'starter-style', get_stylesheet_uri() );

    wp_enqueue_script( 'jquery', '', '', '', true );

    wp_enqueue_script( 'includes', get_template_directory_uri() . '/js/min/includes.min.js', '', '', true );
}
add_action( 'wp_enqueue_scripts', 'starter_scripts' );
22

To do that you will first have to deregister your jQuery script and then register again. If you use jQuery comes with WordPress then following is the function your are looking for.

function starter_scripts() {
    wp_deregister_script( 'jquery' );
    wp_register_script( 'jquery', includes_url( '/js/jquery/jquery.js' ), false, NULL, true );
    wp_enqueue_script( 'jquery' );

    wp_enqueue_style( 'starter-style', get_stylesheet_uri() );
    wp_enqueue_script( 'includes', get_template_directory_uri() . '/js/min/includes.min.js', '', '', true );
}
add_action( 'wp_enqueue_scripts', 'starter_scripts' );

If you use Google CDN hosted version of jQuery then let me know I will modify this code for Google CDN URL.

  • 5
    What do you mean? The solution is about moving jQuery to footer. – Robert hue Sep 3 '15 at 10:58
  • 2
    You might also need to check is_admin() to avoid making changes to the backend jQuery, after all we only really need to optimise the frontend of our sites :) – Tim Malone Oct 20 '16 at 22:10
  • 1
    @TimMalone - actually, you don't - wp_enqueue_scripts is used only on front end while admin_enqueue_scripts is used for back end – dev_masta Mar 4 '17 at 17:18
  • 1
    I think this solution is actually horrible. Are the version tags are removed with this. What is this starter-style and that is this includes.min.js and what has it to do with jQuery. – NextGenThemes Jul 31 '17 at 9:09
  • 1
    @redanimalwar starter-style and includes files are directly from the question. – tehlivi Jan 16 '18 at 18:43
40

Here's another option which avoids having to de-register and re-register:

/**
 * Move jQuery to the footer. 
 */
function wpse_173601_enqueue_scripts() {
    wp_scripts()->add_data( 'jquery', 'group', 1 );
    wp_scripts()->add_data( 'jquery-core', 'group', 1 );
    wp_scripts()->add_data( 'jquery-migrate', 'group', 1 );
}
add_action( 'wp_enqueue_scripts', 'wpse_173601_enqueue_scripts' );

This solution mimics WordPress core by setting the group to 1, which is how WordPress determines if a script should be in the footer or not (I'm not aware of the reasoning for 1, as @jgraup noted in the comments it seems a bit arbitrary).

  • 1
    Interesting. It looks like wp_register_script uses add_data( $handle, 'group', 1 ) to move scripts into the footer. core.trac.wordpress.org/browser/tags/4.5/src/wp-includes/… - Could you expand on why that is? Glancing at your code, 'group' seems a bit arbitrary. But I can see in core.trac.wordpress.org/browser/tags/4.5/src/wp-includes/… how it's used in WP_Scripts->do_item later. Either way, this would seem to be the least destructive answer. – jgraup May 7 '16 at 18:37
  • 2
    I hope someone can comment further on these three upvoted answers. All are different and require some knowledge of WP. Because google requires these scripts to be below the fold, this is an important topic. – ssaltman May 18 '16 at 13:32
  • 2
    Best answer! Note: it works since WordPress 4.2.0 and use it in functions.php in hook 'wp_enqueue_scripts' callback – realmag777 Jul 1 '16 at 18:22
  • Hi I tried the above approach, but it didn't worked. Can anyone help? – iSaumya Aug 31 '16 at 12:13
  • 1
    This is so good! Thank you so much. But, worth noting is as @tehlivi states - WP uses an old version of jQuery - consider deregistering and registering a newer version. – skolind Mar 8 '18 at 9:24
17

A better solution:

add_action( 'wp_default_scripts', 'move_jquery_into_footer' );

function move_jquery_into_footer( $wp_scripts ) {

    if( is_admin() ) {
        return;
    }

    $wp_scripts->add_data( 'jquery', 'group', 1 );
    $wp_scripts->add_data( 'jquery-core', 'group', 1 );
    $wp_scripts->add_data( 'jquery-migrate', 'group', 1 );
}

Why its better then the accepted answer IMO

  1. Changes it at the very core not at a later stage where other things might already messed with it.
  2. The version string it kept in place and not removed!
  3. It does not unregister and reregister a script but it just sets the group value that is essentially the same as if the script would be registered with $footer = true.

About not doing this to the admin

If plugins add inline jquery to the wp_head it will fail when jquery is not loaded at that point, so I suggest you avoid that until you have millions editing your site and you try to performance optimize your admin. This is true for frontend as well so you should watch out for bad coded themes or plugins that assume jquery in the head by using inline jQuery code.

About it not working

You need to be aware that if any other script is loaded to the head that has jQuery in its dependencies, it will also make jQuery load in the head right before itself. And this is good and expected, the reason the wp_enqueue system exists.

  • 1
    While this may answer the question and has some good points to chew on there's too much noise (fluff?) in the answer and is very similar to the previously posted answers with minor code improvements. It may be more well received if it were edited and slimmed down into a more informational version. There's also no real need to call out specific users or answers ( as they may not exist for whatever reason in the future ). – Howdy_McGee Oct 21 '16 at 20:38
  • You call a completely unmentioned and probably better then anything mentioned in other answers "minor code improvements". Well thats simply untrue. Also I did not "call out" anyone, I just mentioned facts that I know to improve coding style and educate readers about it to make them write better code. Seriously I did take quite some time to write the best answer here to far and this is what I get for it. – NextGenThemes Oct 21 '16 at 20:58
  • 4
    The other answers mention nothing about others scripts forcing the jQuery to the head, in fact my answer takes the confusion away from people who don't know why its not working. None of the others answers mention the potential risks ... – NextGenThemes Oct 21 '16 at 21:03
  • This code (as the code of the answer above) returned me a 500 error. I have WordPress 4.9.9 – Marco Panichi Jan 8 at 9:19
  • Hard to believe that this code is causing a 500, you probably have made a mistake in implementing this in your code. This is not really the right place to ask and your outdated WP version is hardly enough information. – NextGenThemes Jan 9 at 18:19
1

I have developed a plugin for this specific problem. This plugin doesn't mess with WordPress jQuery as it is only loaded in the front-end. See: jQuery Manager for WordPress

Why yet another jQuery Updater / Manager / Developer / Debugging tool?

Because none of the developer tools lets you select a specific version of jQuery and/or jQuery Migrate. Providing both the compressed minified / production and the uncompressed / development version. See features below!

✅ Only executed in the front-end, doesn't interfere with WordPress admin/backend and WP customizer (for compatibility reasons) See: https://core.trac.wordpress.org/ticket/45130 and https://core.trac.wordpress.org/ticket/37110

Turn on/off jQuery and/or jQuery Migrate

✅ Activate a specific version of jQuery and/or jQuery Migrate

And much more! The code is open source, so you could study it, learn from it and contribute.


Almost everybody uses the incorrect handle

WordPress actually uses the jquery-core handle, not jquery:

https://github.com/WordPress/WordPress/blob/f84ab5e19f0038a3abec71821c9b8f47a4272942/wp-includes/script-loader.php#L1017

// jQuery
$scripts->add( 'jquery', false, array( 'jquery-core', 'jquery-migrate' ), '1.12.4-wp' );
$scripts->add( 'jquery-core', '/wp-includes/js/jquery/jquery.js', array(), '1.12.4-wp' );
$scripts->add( 'jquery-migrate', "/wp-includes/js/jquery/jquery-migrate$suffix.js", array(), '1.4.1' );

The jquery handle is just an alias to load jquery-core with jquery-migrate

See more info about aliases: wp_register_script multiple identifiers?

The correct way to do it

In my example below I use the official jQuery CDN at https://code.jquery.com I also use script_loader_tag so that I could add some CDN attributes.
You could use the following code:

// Front-end not excuted in the wp admin and the wp customizer (for compatibility reasons)
// See: https://core.trac.wordpress.org/ticket/45130 and https://core.trac.wordpress.org/ticket/37110
function wp_jquery_manager_plugin_front_end_scripts() {
    $wp_admin = is_admin();
    $wp_customizer = is_customize_preview();

    // jQuery
    if ( $wp_admin || $wp_customizer ) {
        // echo 'We are in the WP Admin or in the WP Customizer';
        return;
    }
    else {
        // Deregister WP core jQuery, see https://github.com/Remzi1993/wp-jquery-manager/issues/2 and https://github.com/WordPress/WordPress/blob/91da29d9afaa664eb84e1261ebb916b18a362aa9/wp-includes/script-loader.php#L226
        wp_deregister_script( 'jquery' ); // the jquery handle is just an alias to load jquery-core with jquery-migrate
        // Deregister WP jQuery
        wp_deregister_script( 'jquery-core' );
        // Deregister WP jQuery Migrate
        wp_deregister_script( 'jquery-migrate' );

        // Register jQuery in the head
        wp_register_script( 'jquery-core', 'https://code.jquery.com/jquery-3.3.1.min.js', array(), null, false );

        /**
         * Register jquery using jquery-core as a dependency, so other scripts could use the jquery handle
         * see https://wordpress.stackexchange.com/questions/283828/wp-register-script-multiple-identifiers
         * We first register the script and afther that we enqueue it, see why:
         * https://wordpress.stackexchange.com/questions/82490/when-should-i-use-wp-register-script-with-wp-enqueue-script-vs-just-wp-enque
         * https://stackoverflow.com/questions/39653993/what-is-diffrence-between-wp-enqueue-script-and-wp-register-script
         */
        wp_register_script( 'jquery', false, array( 'jquery-core' ), null, false );
        wp_enqueue_script( 'jquery' );
    }
}
add_action( 'wp_enqueue_scripts', 'wp_jquery_manager_plugin_front_end_scripts' );


function add_jquery_attributes( $tag, $handle ) {
    if ( 'jquery-core' === $handle ) {
        return str_replace( "type='text/javascript'", "type='text/javascript' integrity='sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=' crossorigin='anonymous'", $tag );
    }
    return $tag;
}
add_filter( 'script_loader_tag', 'add_jquery_attributes', 10, 2 );
0
add_action("wp_enqueue_scripts", "myscripts");

function myscripts() { 
   wp_enqueue_script( 'jquery' , '', array(), true); //true for footer
   wp_enqueue_script( 'someScript-js', 'https://domain.com/someScript.js' , '', '', true );
}
-3

Hey only change your code to like this

function starter_scripts() {
        wp_enqueue_style( 'starter-style', get_stylesheet_uri() );
        wp_enqueue_script('jquery');
        wp_enqueue_script( 'includes', get_template_directory_uri() . '/js/min/includes.min.js', array( 'jquery' ) );
    }
    add_action( 'wp_enqueue_scripts', 'starter_scripts' );

i think it work fine

add this lines into your functions.php file

remove_action('wp_head', 'wp_enqueue_scripts', 1);
add_action('wp_footer', 'wp_enqueue_scripts', 5);

then it add script into footer

  • This puts jQuery in the head. I need it in the footer. – Desi Dec 30 '14 at 20:06
  • Hey Desi please check the edited answer I think it help you – Amit Mishra Dec 30 '14 at 20:13
  • 6
    I'm pretty sure this is a terrible idea -- you've effectively prevented anything from loading scripts in the header, not just jQuery, and might be double-enqueuing scripts (haven't looked that deeply). In fact, you probably only need the remove_action / add_action part if you're going to do it this way. – drzaus Jan 26 '16 at 20:34
  • 1
    Indeed terrible idea, don't do this! – NextGenThemes Sep 26 '16 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.