In the new version of Google Tag Manager, one of the most visible and profound changes to the previous version is how tags are fired (and blocked). First of all, there’s the obvious terminological distinction: we talk about triggers now, not rules. Second, triggers have become an integral part of the tag creation workflow, and as such have far more significance in the user interface than before.
The following text is a standalone article. It’s not an update to the guide I wrote for the previous GTM version: Google Tag Manager: Playing By The Rules, and many of the concepts covered therein are still valid.
Triggers introduce many new features and functionalities (a new way of doing auto-event tracking, for example), which require special attention.
Here are the contents of this guide:
- What’s changed
- Technical overview
- Triggers in the workflow
- New trigger creation
- Click and Form triggers
- Triggers in the API
1. What’s changed
There are three major changes, in my opinion, to how triggers compare with the rules of the previous GTM version.
I) Triggers are integrated into the workflow
Sure, this is more a cosmetic thing, but it’s significant. In the previous version of Google Tag Manager, the entry-level for beginners was quite high. This was partly due to the fact that it wasn’t clear just what firing rules and blocking rules do. It got even more confusing once you started learning about stuff like implicit events and conditions, and it didn’t help that the UI gave very little hints about what to do next.
In the new UI, everything is about the workflow. There’s actually a question there now: What triggers this tag to fire? Nothing about firing rules or blocking rules, nothing about event conditions, and so forth. Just the simple, quite self-explanatory question. Of course, to understand what “fire” means, you will need to do some exploration, but the question sets the scene: a tag needs a trigger to fire.
So the biggest obvious change is in the UI. Triggers are an integral part of the workflow, and it’s impossible to not notice them, as you may have with rules in the previous version.
II) You don’t need to explicitly state the ‘event’ condition
The second major change is how you input the event condition. If you’ve read my previous posts about rules, or if you’ve paid attention to the developer guides, you’ll know that every single tag needs an ‘event’ push to fire. With ‘event’ push I’m of course referring to a
dataLayer.push() command that gives a value to the key labelled ‘event’.
This time around, you don’t need to explicitly state the required Event condition (i.e. the value that ‘event’ key needs to have for the tag to fire). Instead, you rely on the available trigger types to set this condition up for you. In fact, the only time you have to explicitly state the name of the event is if you use a Custom Event type, and even then you don’t have to worry about setting it up as a proper condition. You just give the event its name in the required field (you can also use RegEx matching if you want more flexibility):
The point is that since Event is such a super-important part of any tag or trigger, it’s taken out of the normal condition-based setup for triggers and elevated to a grander status.
III) Auto-event tracking has changed
I’ve already written a guide on this, and I’ll cover some of the concepts in this article as well, but this is really significant. Auto-event tracking is no longer tag-based, as it was in the previous version. Instead, you specify the event (click, link click, form submit, error, history event, or timer) by choosing one of the respective trigger types. Once you create a trigger for an auto-event type, GTM automatically starts listening for these events on your site.
This is incredibly convenient, since it reduces clutter in your tags, and it makes event tracking a very central part of any tagging setup (as it should be).
These are, in my view, the biggest changes. As a GTM fanboy, my honest and utterly biased opinion is that the improvements are amazing. There’s a learning curve, and I know that improvements are made to the UI constantly. But the way that triggers have been integrated into the tag workflow, without compromising any of the features carried over from rules, is a wonderful display of design skill.
2. Technical overview
First of all, as I said above, triggers require a
dataLayer.push() or a pre-container-snippet declaration to fire a tag. If a
push() command doesn’t have an ‘event’ key, it becomes merely a “message” that’s added to the message bus. It does nothing for tags. You can see this in the debug mode. If there’s an ‘event’ key in the message, the instance gets the name of the event (unless it’s one of the three default GTM events, see below) or just “Message” if there’s no ‘event’ key in the command:
So if there’s an ‘event’ key in the
push(), a data layer helper object activates and goes through all the active triggers in your container. If any one of these matches the value of the ‘event’ key, and if all the other conditions in the trigger pass, the tag is injected into the site and its code is executed.
Very little has changed, then. You will still need to push ‘event’ values to fire tags. The three default events are still gtm.js (pushed when the container snippet is first rendered in the page template), gtm.dom (pushed when the DOM has loaded), and gtm.load (pushed when the window has loaded):
One thing that has changed is how multiple triggers of same type on the same page are handled.
Since there’s no longer a listener tag that you work with, it’s more than possible that you can have many link click triggers, for example, activating tags on the same page. It doesn’t mean that GTM always attaches a new event listener to the
document node, because that would be an exercise in redundancy. Rather, all the triggers that use the same auto-event, e.g.
gtm.linkClick, are evaluated when the event occurs.
This is fine in most cases, but it’s also possible that you have two Link Click triggers, where on one you have “Check Validation” set to ON, and on the other it’s OFF. This means that the first one only fires if the default action of the link click has not been prevented by other scripts, and the latter fires regardless. Since there’s just one listener controlling the firing of your tags, GTM leverages the
gtm.triggers key in the auto-event object to specify which trigger should fire upon the event:
The value of the key is containerID_triggerID. So in this particular example, I had two Link Click triggers firing on the page, and one of them had “Check Validation” ON. I then clicked a link where I had prevented the default action of the click with
event.preventDefault(). Thus, the
gtm.triggers key tells our tags that only the trigger where “Check Validation” was OFF (id 112) is allowed to fire.
3. Triggers in the workflow
There are two obvious paths to creating triggers: 1) through the tag workflow, and 2) via the Triggers menu.
Regardless of which path you take, you’ll be acquainted with trigger types and the All / Some terminology soon enough.
So, let’s start from the top. I suspect that the most common trigger type for many is the old All Pages trigger. In the new UI, we now have two types that control how this very common trigger works: All Pages and Some Pages.
If you choose All Pages, it’s the same as the old All Pages rule. It will fire your tag on every single page where the GTM container snippet is injected, and more specifically when the value of the ‘event’ key is gtm.js (i.e. as soon as possible in the container load sequence).
If you choose Some Pages, a new screen will pop up. In this screen, you will only see triggers which fire on the Page View event (i.e. when the value of the ‘event’ key is gtm.js). The Some Pages view is very different than anything else in the new UI, and it’s a bit confusing. However, think of it as a quick create / quick edit view for triggers which fire on the Page View event. The other notable thing is that in the Variable drop-down you will only see the built-in Pages variables (Page URL, Page Hostname, Page Path, if you’ve activated them), or user-defined variables of type URL. If you have a Page View trigger that has some other variable as its condition, there’s a bug in this Some Pages view, which will just show a blank selection in the Variable drop-down.
So the Some Pages delimits your choices to triggers around the Page View event, and the variables you can use in the conditions are only a select few.
I guess the reason for this simplification is the sheer popularity of different types of Page View triggers.
In the tag workflow, the next two triggers you’ll see are for Click and Form. These are highlighted no doubt because they have some special use cases. Once again, if you click either one, you will only see triggers that have been created for the respective events (Click, Link Click, or Form). This is all part of the great UI simplification that I think was called for.
By the way, remember that there’s always the red New button that let’s you create a new trigger on the fly.
So the key thing to remember thus far is that when working in the tag workflow, the trigger type you choose delimits what you see in the pop-up screen. However, you can overcome this limitation by choosing the More option at the end of the list. This will show you all of your triggers, and you can choose whichever suits your need.
The first four trigger types you see on the tag workflow, then, are there because they are the most common ones you’ll use (All Pages, Some Pages), or the easiest ones to get wrong (Click, Form). I think they’ve earned the extra attention.
When you click New in the list you find under More (i.e. all your triggers), you’ll enter the trigger creation workflow. This is identical to what you’ll see if you click New after browsing to the Triggers page via the main navigation. So let’s take a look at this workflow next.
4. New trigger creation
When you start creating a new trigger, you should already have a good idea of which Event should fire your tag. Also, it would be best to have all the variables you need up and running, since in its current shape and size, it’s not possible to create new variables in the trigger workflow.
Step one is all-important. You’re choosing the event that fires up the tag. All the other conditions are redundant if you get this one wrong. Here are the ones available at the time of writing:
Fires the tag on one of the three default events – gtm.js (Page View), gtm.dom (DOM Ready), gtm.load (Window Loaded).
Fires the tag when a click event is registered. You can specify whether to listen for any click or specifically a link click.
Fires the tag when a form submit event is registered.
Fires the tag when a change in the browser history state is registered.
Fires the tag when an event whose value you specify is pushed into
Let’s you set up a timer which fires the tag after a given interval (can be set to fire multiple times).
The next step is to choose any trigger-specific settings. With the Page View Trigger, for example, this is the step where you choose what sort of event you’re listening for (Page View, DOM Ready, or Window Loaded).
In the Fire On step, you specify the other conditions you want to take place before any tag that uses this trigger fires. Remember, you do not need to specify the Event condition any more, as it’s implied by the trigger type.
If you choose All <event type>, the only condition in the trigger will be the event type. That means that your tag will fire every single time the event you specified is pushed into
dataLayer. So if, for example, you chose a Click trigger type, and you specify All Clicks as the filter, your tag will fire every single time a click is registered on the site (overkill much?).
If you choose Some <event type>, you will need to specify the other condition(s) for your tag to fire. These can be anything you like, such as data layer variable values, page path matches, etc. As before, you can specify multiple conditions, but if you do, every single one of these conditions must pass for your tag to fire. There’s no either-or relationship here. Conditions are final.
With “Link Click”, “Timer” and “Form” triggers, you’ll see some extra settings in the Trigger, depending on what settings you choose. With “Timer”, you can set up the timer that will fire your tag after a given interval (or given intervals), and with Link Click and Form triggers, you might need to specify the conditions for the listener itself (see next chapter).
And that’s it. If you’re in the tag creation workflow, you will now return to your tag, where you can add other triggers or an exception.
If you want to add multiple triggers to a single tag, it’s the same as before: multiple triggers on the tag are in an either-or relationship. So having multiple triggers on a tag will make the tag fire when any of the triggers fire, which means that your tag can fire multiple times on a page unintentionally.
However, if the underlying event on these multiple triggers is the same (e.g. Click), your tag will fire only once for every click event regardless of if there’s overlap in the triggers.
Adding exceptions is simple enough. Just click Create Exception and choose a trigger which will block the firing of the tag. With exceptions, blocking triggers will always win against firing triggers. However, blocking triggers always need a firing trigger with the same underlying event, otherwise they’re useless. This is because when an ‘event’ key is pushed into
dataLayer, the blocking trigger can only block a trigger which fires on the same ‘event’, since they are evaluated at the same time against the same value of the ‘event’ key (complicated, I know!).
So if you find that your blocking triggers aren’t working, check and make sure that they have a counterpart among the firing triggers, where the underlying Event is the same. And remember that “All Pages” has Page View (‘event’ key value gtm.js) as its underlying event.
5. Click and Form triggers
Since I’ve already written about these in my latest auto-event tracking guide, I want to just briefly explain what makes these two triggers special.
First of all, skip the generic Click listener. Nothing special about that. It just listens to all clicks on your site, regardless of what element you click.
The Link Click trigger, however, only listens for clicks which propagate up to a link (<a/>) node. This means that you can click on a SPAN in a BUTTON in a DIV, but as long as there’s a link wrapper somewhere up the ancestral tree, and as long as the event propagates, GTM will register the event as a link click.
The Form Submit trigger waits for a
submit() event to be dispatched. This means that if some script on your site hijacks the form event and proceeds with some proprietary Ajax function, for example, GTM’s listener will not be able to pick it up.
So remember these two things: Link Click triggers require a click on a link, and Form Submit triggers require a valid browser form submit event. Both need propagation to work.
You might have noticed the two clickable options on these two particular trigger types: Check Validation and Wait For Tags. Once you check either, you’ll see an extra step, Enable When, in the Trigger settings:
The point with Enable When is that you’ll be able to specify a condition for when the trigger is actively listening for the specified event. The most common condition types you’ll use here are page conditions, since you might want to specify that the Form Submit trigger only listens for submit events on pages with forms.
The reason this step was introduced is due to how the two checkable options, especially Wait For Tags, work. So let’s do a quick overview.
Check Validation, when checked, will require that a valid action is propagated to GTM’s listeners. With Link Clicks this means that there’s no
event.preventDefault() called by other scripts. In other words, the link click has to be an actual link click, where the action of clicking the link takes the user to another page.
With the Form Submit, it also checks for a prevented default action. For example, if validation fails, it’s normal to prevent the default action of the submit event.
However, in many cases it’s not just that the default action of the event is prevented, in which case GTM’s listeners will still pick up the event if Check Validation is OFF. Often you’ll see that propagation is stopped as well, which prevents GTM’s listeners from picking anything up. Be sure to see my previous two posts on the topic.
Wait For Tags ensures that all tags that fire on the trigger execute first before proceeding with the action of the event. So if it’s a Link Click trigger, the redirect (or whatever is the action) is halted long enough for all dependent tags to complete execution, after which the action is resumed. Same thing with forms.
And this is the reason you need to specify the secondary filter. Since GTM is the one that halts the default action of the event, it’s possible that it screws something up in the propagation path. I’ve seen cases where the “Wait For Tags” option caused a pop-up blocker to pick up otherwise perfectly innocent lightboxes. Only by deactivating “Wait For Tags” was the problem solved.
My recommendation with this special, link click / form submit secondary filter is this:
Start with the condition Page URL matches RegEx .*, and test thoroughly. If you come across problems, delimit the trigger to fire only on pages where there was no trouble. If all else fails, deactivate the Wait For Tags option, though this might mean that you’ll lose some hits.
Triggers in the API
Triggers are a pollable resource just like anything else in the API. You can list them, retrieve them, update them, delete them, create them, etc.
However, in their current state, there’s a complication. If you want to copy a tag from one container to another, the problem is the trigger ID. Each trigger has an ID, which, I think, is roughly the first available number in a sequence starting with 1. If you use a trigger in a tag, the tag will refer to this trigger using this ID.
Now, when you want to copy this tag to another container, you create a new tag in the target container with this tag resource as the body. The problem is that the target container can already have a trigger with the ID, since they all follow the same logic when assigning the ID!
This means that when copying a tag with triggers to another container, what you actually need to do is this:
- First create the trigger(s) in the new container
- Use the object you receive in the response to see what the new trigger IDs are
- Update the tag resource with the new trigger IDs
- Create the tag in the target container
It’s a pretty complex operation for something as simple as resource cloning, and I hope it will resolve to a simpler solution in the future.
That’s all I have to say about triggers, for now. I’m cautiously apprehensive about possible changes to the UI, as I’m sure there will be in the near future.
To sum it up, triggers work like a charm. It’s so important for usability to have them integrated into the workflow as they are now. At the same time, they haven’t lost any of their power, quite the contrary. The new, Trigger type -based approach to underlying events is an excellent addition, since it helps us focus on what’s important, instead of having to battle with confusing condition syntax.
There are things to be improved in the workflow. I don’t especially enjoy having to work through the Variables page to prepare my triggers (if the variables I need do not exist), and I think there’s still some unification of the UI called for, since, for example, the Some Pages view is so very different from all the other trigger choices.
Please sound off in the comments if I’ve missed something obvious. I would love to keep this guide as up to date as possible.