Roots Discourse

How to put jQuery inline in header? wp_add_inline_script not works

Hi! For performance reasons, I have to put all jQuery code inline in header. In other projects (not Sage), the code above works fine. But in Sage, only jQuery is removed, but the code isn’t inline.

add_action('wp_enqueue_scripts', function () {
  
  // Remove default jQuery
  wp_deregister_script('jquery');

  // Add jQuery inline in <head>
  wp_register_script( 'jquery', '' );
  wp_enqueue_script( 'jquery' );
  $jquery_path = get_template_directory() . '/assets/scripts/jquery.js';
  $jquery_code = file_get_contents( $jquery_path );
  $jquery_ok = wp_add_inline_script( 'jquery', $jquery_code );

  wp_enqueue_style('mytheme/main.css', asset_path('styles/main.css'), false, null);
  wp_enqueue_script('mytheme/main.js', asset_path('scripts/main.js'), ['jquery'], null, true);

  if (is_single() && comments_open() && get_option('thread_comments')) {
    wp_enqueue_script('comment-reply');
  }
}, 100);

If i print $jquery_code, all jQuery code is there. If I run var_dump in $jquery_ok, it returns true. But the code isn’t present in <head>.

What I’m doing wrong?

Are you using Soil? It does a few things that affect jQuery behavior as well as script placement. Some of those features are automatically turned on here.

I also feel like registering an empty script just to hook onto it seems like it might have unintended effects. Maybe try this?

add_action('wp_enqueue_scripts', function () {
  
  // Remove default jQuery
  wp_deregister_script('jquery');

  wp_enqueue_style('mytheme/main.css', asset_path('styles/main.css'), false, null);
  wp_enqueue_script('mytheme/main.js', asset_path('scripts/main.js'), [], null, true);
  wp_add_inline_script(
    'mytheme/main.js', 
    file_get_contents(get_template_directory() . '/assets/scripts/jquery.js'), 
    'before'
  );

  if (is_single() && comments_open() && get_option('thread_comments')) {
    wp_enqueue_script('comment-reply');
  }
}, 100);
1 Like

Hello @alwaysblank! Tks your answer. I’m not using soil.
Your implementation really works. I made a little change, because the word “jquery” must be registered and enqueued as script. Without this, some plugins (like Ninja Forms) don’t recognize which jQuery is loaded, if has no script registered with ‘jquery’ name.

The final code is:

  // Remove default jQuery
  wp_deregister_script('jquery');

  // Register and enqueue a blank jQuery
  wp_register_script( 'jquery', '' );
  wp_enqueue_script( 'jquery' );

  wp_enqueue_style('mytheme/main.css', asset_path('styles/main.css'), false, null);
  wp_enqueue_script('mytheme/main.js', asset_path('scripts/main.js'), [], null, false);
  
  // Add jQuery inline in <head>
  wp_add_inline_script(
    'mytheme/main.js', 
    file_get_contents(get_template_directory() . '/assets/scripts/jquery.js'), 
    'before'
  );

Glad it worked!

I’m curious why you’re doing this, though. You mentioned performance reasons, but by inlining jQuery you’re increasing the size of every page on your site by ~100kb and preventing browsers from caching jQuery and speeding up page loads past the first one. Although inlining jQuery in the head will prevent it from blocking rendering, it’s going to reduce the perceived performance of every single page of your site, because it isn’t cached and will have to be downloaded and parsed every single time someone visits a new page.

Hello @alwaysblank! Yes, there’s these cons… But, increase the size in page and prevent from caching is better than render block. I tried and test a lot for many months and this is the solution I found.

The correct solution is to put an async attribute in the jquery tag, but it cause many problems with other plugins and codes. Without this attribute, we have render block problem.

Then, the better solutions (I found) is to put inline in the header. The sensibility of velocity with this solutions is awesome. Only jquery is inline. All other js is loaded async, because I changed the attribute via WP filter. I have no problems with compatibility and the sites loads really faster.

Sorry my english, I’m from Brazil and I speak portuguese.