Google Tag Manager Pageview Trigger Types

An overlooked and relatively under-documented feature of Google Tag Manager (GTM) is the ability to adjust the trigger type of a pageview trigger. The reason why this capability goes unnoticed to many is because the functionality is not as intuitive as the other custom trigger settings available and it is uncommon to have a lot cases that require varying pageview load scopes. While these reasons alone will make the common user avoid exploring deeper into the functionality, a recent issue I ran into related to this feature changed my perception and made me realize that every user should understand this setting as they would the rest of the trigger functionality.

The Pageview Trigger and Trigger Type Options

When creating pageview triggers there are two built-in options, "All Pages" and "Some Pages", with a third option to customize your own by selecting the “More” button. Within each of these triggers, regardless if it is clearly stated, there is a trigger type associated with that option that tells GTM the stage of the page loading process that should fire the trigger. The first trigger type that is selectable is “Page View”, which fires immediately when the browser parses the page and receives a server request.


(Page View)

The second scope is “DOM Ready”, which fires when the page has been fully loaded, and the final scope is “Window Loaded”, which is triggered after page assets like images and custom javascript tags are loaded.



(DOM Ready)


(Window Loaded)

If you are a Google Tag Manager user who understands the basics of front-end web development, then the technical differences between the trigger types should not be too foreign, but for those who don’t understand the descriptions above, then I highly recommend that you read about how browsers load web pages so you will understand how to debug situations similar to one I will explain later in this article. My discovery of this logic and how it can impact pageview loaded tags has added a new set of considerations that I make with every implementation and has added another reason to my list of why I hate relying on built-in triggers.

What Came First, the Pageview Tag or the dataLayer?

With all of this laid out, let me jump into my issue related to using a built-in pageview trigger and how I resolved it by creating a custom trigger with a later stage pageview trigger type. Unlike custom created triggers, built-in triggers do not clearly inform you of what is happening under the hood like its trigger type and advanced configurations. The only time this information is available is when you are in the GTM debugger mode and can match the trigger name to the action that is happening on the page. As you will likely see when you use a built-in pageview trigger, the trigger fires with the trigger type of “Page View”. This means that the trigger will fire when the page begins to load and become visible. If you want to dive a little bit further into why it is the first trigger type to load, then you have to look no further than clicking on the dataLayer information section in the debugger console that will show the trigger firing when the gtm.js library is loaded.

For most scenarios this is the exact trigger type you want to use to load your pageview because of it fires exactly when the Google Tag Manager library is loaded, but in some circumstances this may have a negative effect on capturing on-page dataLayer information before the trigger is fired. In my case, I was using Google Tag Manager with the ReactJS framework and the speed of this trigger type fired my pageview tag before the dataLayer information was present on the page, which resulted in null values being passed to my custom dimension slots. In order to resolve this problem, I had to create my own pageview trigger and choose a later trigger type that gave GTM enough time to properly parse the dataLayer information to my pageview tag. In the end, I went with the “Window Loaded” trigger type because it fired when the remaining page resources were loaded which made me more confident that I would not run into issues with null values being passed to my dataLayer.

The Importance is in the Details

While it may feel that my solution was simple in nature, the resolution to this issue was hidden away in the GTM documentation and is a concept that I feel is foreign to most GTM users. I learned my lesson the hard way by using built-in triggers without recognizing the settings of the trigger and paid the price. This lesson has made me become more conscious of how I use pageview triggers for my clients and I hope this has taught many GTM users the same lesson without having to face this problem out in the wild.