The jQuery JavaScript library is by almost any means of counting the most popular JavaScript library used in websites around the world. It’s so influential, in fact, that its evolution is tightly bound to the JavaScript standardization effort itself, and it’s an integral part of the JS Foundation’s efforts to build a community for JavaScript developers.

Google Tag Manager, similarly, is the most popular tag management system used in websites, globally. Thus, by way of weak correlation, it makes sense to expect some synergy between the two.

In this article, I want to explore the relationship between the two tools. Both serve a similar purpose - abstraction and facilitation of doing stuff with JavaScript on a web page. I also want to dispel a myth about Google Tag Manager bundling jQuery natively, and I want to explore when it might make sense not to use jQuery.

Table of Contents

No, Google Tag Manager does not come bundled with the jQuery library

Some people have peeked into the depths of the gtm.js library downloaded by the browser when the container snippet is executed. This library contains the GTM container in all its glory. Within the minified, obfuscated JavaScript code, sharp eyes can find the following comment:

This comment might tempt you to think that GTM bundles the full jQuery library within the container JavaScript.

It doesn’t.

The comment is there because Google Tag Manager uses one method that is heavily inspired by a similar functionality in the jQuery library. You can find the source of this in the data-layer-helper GitHub project, where the is_plain_object.js contains the explanation for why there is a licence notice like this:

By the way, the data-layer-helper project is a great way to get acquainted with how GTM’s internal data model works!

Check if jQuery is already running

Chances are, your site is already running jQuery. You can test this by opening the JavaScript console in your favorite web browser. Once the console is open, type in the following text and press enter:

typeof window.jQuery !== 'undefined' ? console.log(window.jQuery.fn.jquery) : 'jQuery not found!'

If your site is running jQuery, you’ll see the version number output into the console. If your site is not running jQuery, you’ll see the text: jQuery not found!.

If jQuery was found, you can tentatively use it in your Custom HTML tags and your Custom JavaScript variables.

However, jQuery is (or at least should be) loaded asynchronously, which means there might be a race condition where you try to call its methods using GTM before the jQuery library has actually loaded. Thus, whenever you want to use jQuery, you should hedge it with some safeguards.

Use jQuery safely

Basically, if you want to use jQuery, you should always check if it has been initialized with something like this:

if (typeof window.jQuery !== 'undefined') {
  // Do something with jQuery
} else {
  // Fallback in case jQuery hasn't been loaded
}

If jQuery is found, you can use it at will, and if it isn’t found, the else block is the fallback you’ll use in such cases. Here’s an example:

function() {
  var el = {{Click Element}};
  if (typeof window.jQuery !== 'undefined') {
    return window.jQuery(el).find('h1').text();
  } else {
    return el.querySelector('h1').textContent;
  }
}

The code in the if block and the code in the else block are essentially the same, though jQuery has some benefits, such as making sure that text() returns the text content regardless of browser type and version.

Load jQuery using Google Tag Manager

If jQuery isn’t used by your site, and you still want to leverage it, you can always load it in a Custom HTML tag.

First, discuss this with your developers. jQuery can introduce quite a bit of bloat into the page, and the developers might have had a good reason not to use jQuery at all. It’s possible they use another library that has the same functionality.

The best way to load jQuery is to use a Custom HTML tag in a tag sequence with whatever tag(s) you have that might need to use jQuery.

Let’s start with what the Custom HTML tag looks like:

<script>
  (function() {
    var el = document.createElement('script');
    el.src = 'https://code.jquery.com/jquery-3.3.1.min.js';
    el.async = true;
    el.addEventListener('load', function() { window.google_tag_manager[{{Container ID}}].onHtmlSuccess({{HTML ID}})});
    el.addEventListener('error', function() { window.google_tag_manager[{{Container ID}}].onHtmlFailure({{HTML ID}})});
    document.head.appendChild(el);
  })();
</script>

You’ll need to enable the Container ID and HTML ID built-in variables for this. Do not add any triggers to this tag.

Basically, you create an asynchronous <script> load request for the jQuery library from jQuery’s own CDN (content distribution network). Because it’s asynchronous, you also add a load listener, which fires when the library has loaded successfully, and an error listener, which fires if the library failed to load due to an error.

It’s not perfect, since sometimes just because the library loaded doesn’t mean it managed to execute correctly (if there are conflicts in the page’s global namespace, for example), and an error isn’t always thrown if the library fails to load.

Once you’ve created that Custom HTML tag, scroll down to its Advanced settings, and set its Tag firing options to Once per page.

This is because regardless of how many tag sequences it’s in, you only want to load the jQuery library once per page.

Next, you need to open every tag that needs jQuery, scroll down to their Advanced settings, and add the jQuery loader as a setup tag in the sequence:

If you want to block the tag from running in case jQuery did not load, you can check the “Don’t fire tag if setup_tag fails or is paused”. But this is a bit drastic. Instead, you might want to simply see the tip in the previous chapter to run a fallback in case jQuery is not found.

I want to repeat what I wrote above: discuss with your developers first. jQuery isn’t big, but it’s still bloat if you only need it for a handful of things. Which leads me to the next point.

You don’t always have to use jQuery

Check out this wonderful website: You Might Not Need jQuery. It’s a service that helps you rewrite jQuery methods using vanilla JavaScript.

If you find yourself only needing jQuery for a handful of things, it might be better to just use native JavaScript methods rather than load an entire library to perform simple tasks.

How to write an HTTP POST request with and without jQuery How to write an HTTP POST request with and without jQuery

Here are my own, personal rules of thumb:

  1. If the site already loads the jQuery library, use it at will. Just make sure to avoid race conditions if jQuery is loaded asynchronously (as it should).

  2. If the site is not running jQuery, look at the complexity of the tasks you want to do. If you only need to do simple DOM traversal or trivial HTTP requests, look into using native JavaScript rather than loading the library.

  3. If you must load jQuery, use a recent, minified version of the library. Load it asynchronously, and use tag sequencing to ensure the dependency has loaded before it is used by the main tag.

Summary

jQuery is a great tool in web development. There’s a reason it’s the most popular JavaScript library on the web.

However, native JavaScript is spectacularly useful, too, even if you might have type in some extra characters compared to jQuery’s helper methods.

I’ve always tried to avoid using jQuery or, really, any helper library because I think it’s important to understand how the underlying JavaScript engine in the browser works. If you always use jQuery, you’ll easily ignore things like the nuances of browser support, performance optimization, and how to write good, readable code in general.

Similar to Google Tag Manager, jQuery is a great tool, but you have to earn the right to use it by understanding how it works on the web page. Ignorance to what jQuery actually does can lead to catastrophic results, when you write business critical code in your tags, relying on an outdated version of jQuery, or using methods that totally kill performance.