I’ve written about this before here and here, but this issue remains probably the biggest problem users have when implementing Google Tag Manager.

Tip 10: Resolve conflicts with GTM’s listeners

The tip title is actually wrong. You’re not fixing Google Tag Manager listeners. Rather, you’re resolving conflicts that other scripts on your page might introduce.

GTM’s event listening is based on something called event delegation. Event delegation makes use of the document object model (DOM) and its tree-like hierarchy.

When a click occurs on a node, such as a link element, the click event begins to bubble up the DOM tree. It passes through every single ancestral node on its way to the top. This means that instead of attaching a listener to every single link element, GTM attaches the listener on the top-most document node (the document itself). This way it will capture the event once it has bubbled up all the way to the top. It’s much more economical to listen for events this way, as you don’t have to pollute the elements with individual handlers.

A conflict occurs when somewhere along this way up, the event’s path is obstructed. The term we use here is that its propagation is stopped. If this happens, GTM’s listeners never capture the event, and thus they will never work with your tags.

The most common way that propagation is stopped is:

return false; in a jQuery event handler

If there’s a return false; in your jQuery event handler, propagation is stopped. The return false; statement in jQuery combines both preventDefault() AND stopPropagation() on the event object. There’s an easy fix to this: invoke ONLY preventDefault(). This should work almost always, unless there’s a specific reason you want propagation to stop.

For example:

// Before - propagation stopped
$('a#toTop').on('click', function() {
  // some code
  return false;
});
// After - propagation not stopped
$('a#toTop').on('click', function(e) {
  e.preventDefault();
  // some code
});

preventDefault() prevents the default action of the click but it doesn’t stop propagation. I’d say around 95% of the time, this is enough for your dynamic scripts.

There are other ways to stop propagation (such as an explicit call to e.stopPropagation()), but the jQuery scenario is by far the most common one.

Fix it!

The first thing you want to try is to uncheck Check Validation in your link click or form submit trigger. If Check Validation is on, it means that GTM’s handlers will not fire even with a proper preventDefault(). The listener will only fire if an uninterrupted / untouched event object propagates to the document node.

The second thing is to look through your scripts and try to find the offending jQuery / other handlers. Look for hints of propagation being stopped. Fix them yourself or ask your developers to fix them. Look for custom AJAX functions as well, especially with forms. With forms, it’s possible that a submit() is never called. Instead, an AJAX POST request is sent to a backend validator or something.

The third thing you should try is the best: talk to your developers. Educate them. Tell them that GTM’s listeners require that clicks and form submits propagate to the document node. If they get that, they should be able to fix it. If they don’t understand this, make them learn the basics of JavaScript again.