Skip to content

Page View Triggers

GTM gives you three distinct “page view” trigger types, each firing at a different point in the browser’s page load lifecycle. They look similar in the interface, but their timing differences matter. Firing a tag too early means reading from a DOM that is not ready. Firing too late delays data you need immediately. Getting this right prevents an entire class of silent bugs.

Fires as soon as GTM’s container has downloaded and initialized. This is the earliest moment any tag can fire. At this point, the browser is still parsing and rendering HTML — the DOM is not fully constructed. JavaScript on the page may not have run yet.

Use when: The tag does not need to read the DOM, does not depend on page content loading, and should fire as early as possible. The GA4 Configuration tag belongs here.

Technical equivalent: There is no exact browser equivalent. It fires after GTM’s own initialization completes, which typically happens 50-200ms after the HTML begins parsing.

Fires when the HTML document has been fully parsed and the DOM tree is complete — equivalent to the browser’s DOMContentLoaded event. Images, stylesheets, and iframes may still be loading, but all HTML elements exist and are accessible via JavaScript.

Use when: The tag needs to read element attributes, access DOM content, or depends on the page structure being complete. Custom HTML tags that query the DOM must fire here or later, or they will fail silently.

Technical equivalent: document.addEventListener('DOMContentLoaded', ...). If you know when DOMContentLoaded fires relative to your tag’s needs, you know when DOM Ready fires.

Fires when the entire page has finished loading — including images, iframes, video thumbnails, fonts, and all sub-resources. This is the browser’s window.onload event.

Use when: The tag is non-critical for the user experience and you want to avoid any chance of it delaying interactive content. Session replay tools (Hotjar, Clarity), chat widgets, and survey tools often work fine on Window Loaded.

Technical equivalent: window.addEventListener('load', ...). This fires last among the three triggers.

0ms HTML starts arriving
~50ms GTM script tag parsed and starts loading
~200ms GTM container downloaded
→ gtm.js fires (Page View triggers)
~300ms HTML fully parsed, DOM complete
→ gtm.dom fires (DOM Ready triggers)
~1500ms All images, fonts, iframes loaded
→ gtm.load fires (Window Loaded triggers)

These timings are illustrative — actual timing depends on page size, network speed, and server response time. What matters is the sequence: gtm.js always fires before gtm.dom, which always fires before gtm.load.

This is the practical guide:

Tag typeTrigger
GA4 Configuration tagPage View
Google Ads conversion linkerPage View
Consent Mode defaults updateInline script before GTM (not a GTM trigger)
GA4 Event tag for custom eventsCustom Event trigger (not a page view trigger)
Custom HTML that reads DOM elementsDOM Ready
Session replay / screen recordingWindow Loaded
Chat widget (Intercom, Drift)Window Loaded
Heatmap toolsWindow Loaded

The recommendation for GA4 Configuration is clear: fire it on Page View. Every millisecond it fires earlier increases the window available for GA4 event tags to send properly associated hits. If your GA4 Configuration fires on Window Loaded and a user bounces after 0.5 seconds, the configuration never initializes and no GA4 data is sent.

The default page view trigger fires on all pages with no filtering. This is correct for your GA4 Configuration tag — you want it on every page.

Tag Configuration

GA4 - Configuration

Type
Google Analytics: GA4 Configuration
Trigger
Page View - All Pages (gtm.js)
Variables
Measurement ID

Use “Some Page Views” to add URL-based conditions. Common patterns:

// Fire only on product pages
Page Path contains /products/
// Fire only on the checkout
Page Path starts with /checkout
// Fire on specific pages
Page URL matches RegEx .*(pricing|features|about).*
// Exclude a page
Page Path does not contain /thank-you
  1. Create a new trigger with type Page View (or DOM Ready / Window Loaded)
  2. Switch from All Page Views to Some Page Views
  3. Add your filter conditions
  4. Name it clearly: PV - Product Pages, PV - Checkout Only

The most common use of conditional page view triggers is URL-based filtering. GTM provides several built-in variables for this:

VariableValueExample
Page URLFull URLhttps://example.com/products?color=red
Page HostnameDomain onlyexample.com
Page PathPath only/products
Query StringQuery string onlycolor=red
ReferrerReferring URLhttps://google.com

For most filtering, Page Path is the right choice. It does not include the domain (so it works across environments) and does not include query parameters (which change frequently and vary per user).

// Prefer Page Path for filtering
Page Path starts with /shop/
Page Path equals /checkout/success
// Use Page URL only when you need to match query parameters
Page URL contains ?source=email
// Use Referrer for acquisition-based filtering
Referrer contains google.com

In single-page applications, page view triggers behave differently. GTM fires gtm.js, gtm.dom, and gtm.load only once — on the initial page load. Subsequent SPA navigations do not trigger new page view events.

For SPA tracking, you have two options:

  1. History Change trigger: GTM’s built-in trigger for pushState/popstate events. Fires automatically when the URL changes.
  2. Custom Event trigger with page_view: Push your own page_view event to the dataLayer from your framework’s router.

The second option is more reliable. For a full explanation, see SPA Setup.

Using Window Loaded as the default for everything

Section titled “Using Window Loaded as the default for everything”

Some GTM tutorials recommend Window Loaded as a “safe” default because everything is definitely loaded by then. This is poor advice. Firing your GA4 Configuration on Window Loaded means analytics initialization is delayed by the full page load time. On a slow connection or a heavy page, that can be a 3-5 second delay — plenty of time for a fast user to bounce and be completely untracked.

Firing DOM-dependent Custom HTML on Page View

Section titled “Firing DOM-dependent Custom HTML on Page View”

Custom HTML tags that use document.querySelector() or document.getElementById() often fire on Page View because the developer wants them as early as possible. But on Page View, the DOM is not ready. The query returns null, the code throws an error, and GTM silently swallows it. Move these tags to DOM Ready.

One trigger per use case, not one trigger for everything

Section titled “One trigger per use case, not one trigger for everything”

Creating a single “All Pages - Page View” trigger and attaching it to every tag is an anti-pattern. It couples the timing of all your tags together. Create specific triggers (or name them clearly) so you can change one tag’s timing without affecting others.

Not verifying trigger timing in Preview mode

Section titled “Not verifying trigger timing in Preview mode”

GTM Preview mode shows the exact sequence of events that fired on a page load. Open Preview, navigate to a page, and check the Events panel. You should see gtm.js, then gtm.dom, then gtm.load in order. If a tag is firing at the wrong time, Preview mode will show you exactly which event triggered it.