1553 lines
33 KiB
Markdown
1553 lines
33 KiB
Markdown
# Google Tag Manager - Triggers
|
|
|
|
## Overview
|
|
|
|
Triggers define when tags should fire in Google Tag Manager. They are the "when" component of the Tag-Trigger-Variable system that powers GTM implementations.
|
|
|
|
**What Triggers Do:**
|
|
|
|
- Control when tags execute
|
|
- Evaluate conditions based on page events and user interactions
|
|
- Filter tag firing using conditions and variables
|
|
- Support multiple events types (page views, clicks, form submissions, custom events)
|
|
|
|
## Regular Expressions in Triggers (RE2 Format)
|
|
|
|
**CRITICAL:** Google Tag Manager uses **RE2 (GoLang regex)** format, NOT standard JavaScript/PCRE regex.
|
|
|
|
### RE2 vs Standard Regex
|
|
|
|
**NOT Supported in RE2:**
|
|
|
|
- ❌ Backreferences: `\1`, `\2`, `\g{name}`
|
|
- ❌ Lookahead assertions: `(?=...)`, `(?!...)`
|
|
- ❌ Lookbehind assertions: `(?<=...)`, `(?<!...)`
|
|
- ❌ Conditional expressions: `(?(condition)yes|no)`
|
|
- ❌ Possessive quantifiers: `*+`, `++`
|
|
|
|
**Supported in RE2:**
|
|
|
|
- ✅ Character classes: `[abc]`, `[^abc]`, `[a-z]`
|
|
- ✅ Quantifiers: `*`, `+`, `?`, `{n,m}`
|
|
- ✅ Anchors: `^`, `$`, `\A`, `\z`
|
|
- ✅ Perl character classes: `\d`, `\w`, `\s`
|
|
- ✅ Groups: `(...)`, `(?:...)` (non-capturing)
|
|
- ✅ Named groups: `(?P<name>...)`
|
|
- ✅ Alternation: `|`
|
|
- ✅ Case-insensitive flag: `(?i)`
|
|
|
|
### Common RE2 Patterns for Triggers
|
|
|
|
**Match Page URLs:**
|
|
|
|
```regex
|
|
# Exact match
|
|
^https://example\.com/page$
|
|
|
|
# Contains specific path
|
|
/checkout/
|
|
|
|
# Query parameter present
|
|
\?utm_source=
|
|
|
|
# Multiple domains
|
|
^https://(www\.)?example\.(com|net)
|
|
|
|
# Product pages (ends with digits)
|
|
/product/\d+$
|
|
|
|
# Any subdomain
|
|
^https://[^.]+\.example\.com/
|
|
```
|
|
|
|
**Match Click URLs:**
|
|
|
|
```regex
|
|
# PDF downloads
|
|
\.pdf$
|
|
|
|
# External links (not your domain)
|
|
^https?://(?!example\.com)
|
|
|
|
# Telephone links
|
|
^tel:
|
|
|
|
# Email links
|
|
^mailto:
|
|
|
|
# File downloads
|
|
\.(pdf|docx?|xlsx?|zip)$
|
|
```
|
|
|
|
**Match Form IDs and Classes:**
|
|
|
|
```regex
|
|
# Form ID starts with "contact"
|
|
^contact
|
|
|
|
# Form class contains "newsletter"
|
|
newsletter
|
|
|
|
# Multiple form IDs
|
|
^(contact-form|signup-form|subscribe)$
|
|
```
|
|
|
|
**Case-Insensitive Matching:**
|
|
|
|
```regex
|
|
# Case-insensitive flag at start
|
|
(?i)^/checkout
|
|
|
|
# Matches: /checkout, /Checkout, /CHECKOUT
|
|
(?i)\.pdf$
|
|
|
|
# Matches: .pdf, .PDF, .Pdf
|
|
```
|
|
|
|
**Path Matching:**
|
|
|
|
```regex
|
|
# Blog posts with year/month/day structure
|
|
^/blog/\d{4}/\d{2}/\d{2}/
|
|
|
|
# Category pages with optional subcategory
|
|
^/category/[\w-]+(/[\w-]+)?$
|
|
|
|
# User profile pages
|
|
^/user/[^/]+$
|
|
|
|
# API endpoints
|
|
^/api/v\d+/
|
|
```
|
|
|
|
**See Also:**
|
|
|
|
- [Best Practices - Regular Expressions in GTM](./best-practices.md#regular-expressions-in-google-tag-manager-re2-format) for RE2 guidelines
|
|
- Complete RE2 syntax: `.claude/skills/gtm-core/gtm-core/references/google-rew-regular-expressions-syntax.txt`
|
|
|
|
## Trigger Basics
|
|
|
|
### How Triggers Work
|
|
|
|
1. **Event occurs** - User action or page state change
|
|
2. **Trigger evaluates** - GTM checks trigger conditions
|
|
3. **Conditions match** - All filters evaluate to true
|
|
4. **Tag fires** - Associated tag executes
|
|
|
|
### Trigger Components
|
|
|
|
- **Trigger Type** - Defines the event (Page View, Click, Custom Event, etc.)
|
|
- **Trigger Conditions** - Filters that must match for trigger to fire
|
|
- **Operator** - How to compare values (equals, contains, matches regex, etc.)
|
|
- **Value** - The expected value to match against
|
|
|
|
### Trigger Evaluation
|
|
|
|
Triggers evaluate on each GTM event:
|
|
|
|
```
|
|
Event: gtm.dom
|
|
→ Check all triggers for event type "DOM Ready"
|
|
→ Evaluate each trigger's conditions
|
|
→ Fire matching tags
|
|
```
|
|
|
|
### Multiple Conditions (AND Logic)
|
|
|
|
When a trigger has multiple conditions, ALL must be true:
|
|
|
|
```
|
|
Condition 1: Page Path contains /checkout
|
|
AND
|
|
Condition 2: Referrer contains google.com
|
|
AND
|
|
Condition 3: Cookie - user_type - equals - premium
|
|
|
|
All three conditions must match for trigger to fire
|
|
```
|
|
|
|
### Some/All Pages or Elements
|
|
|
|
Many triggers offer "Some" or "All" options:
|
|
|
|
**All Pages:**
|
|
- Fires on every page
|
|
- No additional conditions
|
|
|
|
**Some Pages:**
|
|
- Fires only when conditions match
|
|
- Requires at least one filter condition
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Trigger Type: Page View
|
|
This trigger fires on: Some Page Views
|
|
Page Path contains /products/
|
|
AND
|
|
Page Hostname equals www.example.com
|
|
```
|
|
|
|
## Trigger Types
|
|
|
|
### Pageview Triggers
|
|
|
|
#### Page View
|
|
|
|
Fires when GTM container loads on a page.
|
|
|
|
**Event:** `gtm.js`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Fire tags on all pages
|
|
- Track specific page views
|
|
- Initialize analytics configuration
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Page View
|
|
This trigger fires on: All Pages
|
|
```
|
|
|
|
or
|
|
|
|
```
|
|
Trigger Type: Page View
|
|
This trigger fires on: Some Page Views
|
|
Page Path contains /products/
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Pageview - All Pages
|
|
Type: Page View
|
|
Fires on: All Pages
|
|
Use: Fire GA4 Config tag everywhere
|
|
```
|
|
|
|
```
|
|
Name: Pageview - Thank You Pages
|
|
Type: Page View
|
|
Fires on: Some Page Views
|
|
Page Path matches RegEx: /(thank-you|confirmation|success)
|
|
Use: Fire conversion tags
|
|
```
|
|
|
|
```
|
|
Name: Pageview - Product Category
|
|
Type: Page View
|
|
Fires on: Some Page Views
|
|
Page Path starts with /category/
|
|
AND Page Path does not contain /admin/
|
|
Use: Track category page views
|
|
```
|
|
|
|
#### DOM Ready
|
|
|
|
Fires when the DOM (Document Object Model) is fully constructed but before all resources load.
|
|
|
|
**Event:** `gtm.dom`
|
|
|
|
**Timing:** After DOM built, before images/stylesheets fully loaded
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Access DOM elements before page fully renders
|
|
- Set up event listeners
|
|
- Modify page content early
|
|
- Better performance than Window Loaded for tags that don't need full page load
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: DOM Ready
|
|
This trigger fires on: All Pages
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Name: DOM Ready - All Pages
|
|
Type: DOM Ready
|
|
Fires on: All Pages
|
|
Use: Initialize chat widget before page fully loads
|
|
```
|
|
|
|
**Timeline:**
|
|
|
|
```
|
|
1. GTM Container Loads → Page View (gtm.js)
|
|
2. DOM Constructed → DOM Ready (gtm.dom)
|
|
3. All Resources Loaded → Window Loaded (gtm.load)
|
|
```
|
|
|
|
#### Window Loaded
|
|
|
|
Fires when the page is fully loaded, including all resources (images, scripts, stylesheets).
|
|
|
|
**Event:** `gtm.load`
|
|
|
|
**Timing:** After all page resources completely loaded
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Tags that need complete page context
|
|
- Performance measurements (load time)
|
|
- Tags that shouldn't impact page speed
|
|
- Third-party widgets that depend on full page load
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Window Loaded
|
|
This trigger fires on: All Pages
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Name: Window Loaded - Home Page
|
|
Type: Window Loaded
|
|
Fires on: Some Page Views
|
|
Page Path equals /
|
|
Use: Fire non-critical tags after page fully loads
|
|
```
|
|
|
|
**When to Use Each Pageview Trigger:**
|
|
|
|
| Trigger Type | Use When | Performance Impact |
|
|
|-------------|----------|-------------------|
|
|
| Page View | Need tag to fire immediately | Low |
|
|
| DOM Ready | Need DOM access, don't need resources | Medium |
|
|
| Window Loaded | Need full page context, non-critical tags | High (delayed) |
|
|
|
|
### Click Triggers
|
|
|
|
#### All Elements
|
|
|
|
Fires when user clicks any element on the page.
|
|
|
|
**Event:** `gtm.click`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track button clicks
|
|
- Track link clicks
|
|
- Track custom element interactions
|
|
- Track clicks on dynamically generated elements
|
|
|
|
**Built-in Click Variables:**
|
|
|
|
- `{{Click Element}}` - The clicked DOM element
|
|
- `{{Click Classes}}` - CSS classes of clicked element
|
|
- `{{Click ID}}` - ID attribute of clicked element
|
|
- `{{Click Target}}` - Target attribute value
|
|
- `{{Click URL}}` - href attribute (for links)
|
|
- `{{Click Text}}` - Text content of clicked element
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: All Elements
|
|
This trigger fires on: Some Clicks
|
|
Click Text equals Sign Up
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Click - CTA Buttons
|
|
Type: All Elements
|
|
Fires on: Some Clicks
|
|
Click Classes contains cta-button
|
|
Use: Track call-to-action button clicks
|
|
```
|
|
|
|
```
|
|
Name: Click - Add to Cart
|
|
Type: All Elements
|
|
Fires on: Some Clicks
|
|
Click ID equals add-to-cart-btn
|
|
Use: Track add to cart events
|
|
```
|
|
|
|
```
|
|
Name: Click - Outbound Links
|
|
Type: All Elements
|
|
Fires on: Some Clicks
|
|
Click URL does not contain example.com
|
|
AND Click URL matches RegEx: ^https?://
|
|
Use: Track external link clicks
|
|
```
|
|
|
|
```
|
|
Name: Click - Download PDFs
|
|
Type: All Elements
|
|
Fires on: Some Clicks
|
|
Click URL matches RegEx: \.pdf$
|
|
Use: Track PDF downloads
|
|
```
|
|
|
|
**Enable Click Variables:**
|
|
|
|
Variables → Configure Built-In Variables → Clicks
|
|
|
|
#### Just Links
|
|
|
|
Fires only when user clicks links (`<a>` tags with `href` attribute).
|
|
|
|
**Event:** `gtm.linkClick`
|
|
|
|
**Optimized for:** Link tracking with automatic wait time for tag to fire before navigation
|
|
|
|
**Wait for Tags:** GTM waits up to 2 seconds for tags to fire before following link
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track navigation links
|
|
- Track external links
|
|
- Track file downloads
|
|
- Outbound link tracking
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Just Links
|
|
This trigger fires on: Some Link Clicks
|
|
Click URL contains example.com
|
|
Wait for Tags: 2000 milliseconds
|
|
Check Validation: false
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Click - External Links
|
|
Type: Just Links
|
|
Fires on: Some Link Clicks
|
|
Click URL does not contain {{Page Hostname}}
|
|
AND Click URL matches RegEx: ^https?://
|
|
Use: Track clicks to external websites
|
|
```
|
|
|
|
```
|
|
Name: Click - Email Links
|
|
Type: Just Links
|
|
Fires on: Some Link Clicks
|
|
Click URL starts with mailto:
|
|
Use: Track email link clicks
|
|
```
|
|
|
|
```
|
|
Name: Click - Phone Links
|
|
Type: Just Links
|
|
Fires on: Some Link Clicks
|
|
Click URL starts with tel:
|
|
Use: Track phone number clicks
|
|
```
|
|
|
|
```
|
|
Name: Click - File Downloads
|
|
Type: Just Links
|
|
Fires on: Some Link Clicks
|
|
Click URL matches RegEx: \.(pdf|docx?|xlsx?|zip|csv)$
|
|
Use: Track file download clicks
|
|
```
|
|
|
|
**Settings:**
|
|
|
|
- **Wait for Tags:** Max time (ms) to wait before following link (default: 2000ms)
|
|
- **Check Validation:** Wait for form validation before firing (default: false)
|
|
- **Enable when:** Additional conditions for trigger to be active
|
|
|
|
**All Elements vs Just Links:**
|
|
|
|
| Feature | All Elements | Just Links |
|
|
|---------|-------------|------------|
|
|
| Fires on | Any element | Only `<a>` tags |
|
|
| Wait for tags | No | Yes (prevents navigation) |
|
|
| Performance | Lower (all clicks) | Better (links only) |
|
|
| Use for | Buttons, divs, any element | Navigation, downloads |
|
|
|
|
### User Engagement Triggers
|
|
|
|
#### Element Visibility
|
|
|
|
Fires when a specific element becomes visible in the viewport.
|
|
|
|
**Event:** `gtm.elementVisibility`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track ad impressions
|
|
- Track scroll-to-content
|
|
- Lazy load tracking
|
|
- Measure content engagement
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Element Visibility
|
|
Selection Method: ID / CSS Selector
|
|
Element ID: featured-product
|
|
OR
|
|
Element Selector: .product-card
|
|
|
|
When to fire this trigger:
|
|
☑ Once per page
|
|
☐ Once per element
|
|
☐ Every time an element appears on screen
|
|
|
|
Minimum Percent Visible: 50%
|
|
Minimum On-Screen Duration: 1000 milliseconds
|
|
|
|
This trigger fires on: All Pages
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Visibility - Hero Banner
|
|
Type: Element Visibility
|
|
Element ID: hero-banner
|
|
Fires when: Once per page
|
|
Percent Visible: 50%
|
|
On-Screen Duration: 2000ms
|
|
Use: Track hero banner impressions
|
|
```
|
|
|
|
```
|
|
Name: Visibility - Product Cards
|
|
Type: Element Visibility
|
|
Element Selector: .product-card
|
|
Fires when: Once per element
|
|
Percent Visible: 75%
|
|
On-Screen Duration: 500ms
|
|
Fires on: Some Pages
|
|
Page Path contains /products/
|
|
Use: Track which products users view
|
|
```
|
|
|
|
**Advanced Options:**
|
|
|
|
- **Observe DOM changes** - Track dynamically added elements
|
|
- **Advanced matching** - Multiple selectors using CSS
|
|
|
|
**Built-in Variables:**
|
|
|
|
Enable Element Visibility variables:
|
|
- `{{Percent Visible}}` - Percentage of element visible
|
|
- `{{On-Screen Duration}}` - How long visible (ms)
|
|
|
|
#### Form Submission
|
|
|
|
Fires when a user submits a form.
|
|
|
|
**Event:** `gtm.formSubmit`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track form submissions
|
|
- Track lead generation
|
|
- Track newsletter signups
|
|
- Fire conversion tags
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Form Submission
|
|
This trigger fires on: All Forms
|
|
OR
|
|
This trigger fires on: Some Forms
|
|
Form ID equals contact-form
|
|
|
|
Enable when:
|
|
(optional conditions)
|
|
|
|
Wait for Tags: 2000 milliseconds
|
|
Check Validation: True
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Form Submit - Contact Form
|
|
Type: Form Submission
|
|
Fires on: Some Forms
|
|
Form ID equals contact-form
|
|
OR Form Classes contains contact-form
|
|
Check Validation: True
|
|
Use: Track contact form submissions
|
|
```
|
|
|
|
```
|
|
Name: Form Submit - Newsletter Signup
|
|
Type: Form Submission
|
|
Fires on: Some Forms
|
|
Form ID matches RegEx: (newsletter|subscribe)
|
|
Use: Track newsletter signups
|
|
```
|
|
|
|
```
|
|
Name: Form Submit - All Forms
|
|
Type: Form Submission
|
|
Fires on: All Forms
|
|
Check Validation: True
|
|
Except:
|
|
Form ID equals search-form (handled separately)
|
|
Use: Track all form submissions except search
|
|
```
|
|
|
|
**Settings:**
|
|
|
|
- **Wait for Tags:** Time to wait for tags before form submits (default: 2000ms)
|
|
- **Check Validation:** Only fire if form passes HTML5 validation (recommended: true)
|
|
|
|
**Built-in Form Variables:**
|
|
|
|
Enable in Variables → Configure:
|
|
- `{{Form ID}}` - Form's ID attribute
|
|
- `{{Form Classes}}` - Form's CSS classes
|
|
- `{{Form Target}}` - Form's target attribute
|
|
- `{{Form URL}}` - Form's action URL
|
|
- `{{Form Text}}` - Text content within form
|
|
|
|
**Important:** Never capture form field values containing PII (emails, names, phone numbers).
|
|
|
|
#### Scroll Depth
|
|
|
|
Fires when user scrolls to specific depths on a page.
|
|
|
|
**Event:** `gtm.scrollDepth`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Measure content engagement
|
|
- Track how far users scroll
|
|
- Identify drop-off points
|
|
- Understand content consumption
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Scroll Depth
|
|
|
|
Vertical Scroll Depths:
|
|
Percentages: 25, 50, 75, 90, 100
|
|
OR
|
|
Pixels: 500, 1000, 2000
|
|
|
|
This trigger fires on: All Pages
|
|
OR
|
|
This trigger fires on: Some Pages
|
|
Page Path contains /blog/
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Scroll Depth - Blog Posts
|
|
Type: Scroll Depth
|
|
Percentages: 25, 50, 75, 100
|
|
Fires on: Some Pages
|
|
Page Path starts with /blog/
|
|
Use: Measure blog post engagement
|
|
```
|
|
|
|
```
|
|
Name: Scroll Depth - Home Page
|
|
Type: Scroll Depth
|
|
Percentages: 10, 25, 50, 75, 90
|
|
Fires on: Some Pages
|
|
Page Path equals /
|
|
Use: Track homepage scroll behavior
|
|
```
|
|
|
|
```
|
|
Name: Scroll Depth - Long Form Content
|
|
Type: Scroll Depth
|
|
Pixels: 1000, 2000, 3000, 4000
|
|
Fires on: Some Pages
|
|
Page Path contains /guides/
|
|
Use: Track reading depth on long guides
|
|
```
|
|
|
|
**Built-in Scroll Variables:**
|
|
|
|
Enable Scroll Depth variables:
|
|
- `{{Scroll Depth Threshold}}` - The threshold that was reached (e.g., "75")
|
|
- `{{Scroll Depth Units}}` - "percent" or "pixels"
|
|
- `{{Scroll Direction}}` - "vertical" or "horizontal"
|
|
|
|
**Best Practices:**
|
|
|
|
- Don't track too many thresholds (max 5-7)
|
|
- Use percentages for responsive design
|
|
- Consider page length when setting thresholds
|
|
- Combine with time on page for engagement metrics
|
|
|
|
#### YouTube Video
|
|
|
|
Fires when users interact with embedded YouTube videos.
|
|
|
|
**Event:** `gtm.video`
|
|
|
|
**Requires:** YouTube video embedded via iframe
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track video starts
|
|
- Track video completion
|
|
- Measure video engagement
|
|
- Track video progress
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: YouTube Video
|
|
Capture: Start, Complete, Pause, Seeking, Buffering, Progress
|
|
|
|
Add JavaScript API support to all HTML5 videos: ☑
|
|
|
|
Progress Threshold (%): 10, 25, 50, 75, 90
|
|
|
|
This trigger fires on: Some Videos
|
|
Video URL contains product-demo
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Video - All Interactions
|
|
Type: YouTube Video
|
|
Capture:
|
|
☑ Start
|
|
☑ Complete
|
|
☑ Pause
|
|
☑ Progress
|
|
Progress: 25, 50, 75
|
|
Fires on: All Videos
|
|
Use: Track all video engagement
|
|
```
|
|
|
|
```
|
|
Name: Video - Product Demo Complete
|
|
Type: YouTube Video
|
|
Capture:
|
|
☑ Complete
|
|
Fires on: Some Videos
|
|
Video URL contains product-demo
|
|
OR Video Title contains Product Demo
|
|
Use: Track product demo completion
|
|
```
|
|
|
|
**Built-in Video Variables:**
|
|
|
|
Enable Video variables:
|
|
- `{{Video Status}}` - start, pause, complete, progress, etc.
|
|
- `{{Video URL}}` - YouTube video URL
|
|
- `{{Video Title}}` - Video title from YouTube
|
|
- `{{Video Duration}}` - Total video length (seconds)
|
|
- `{{Video Current Time}}` - Playback position (seconds)
|
|
- `{{Video Percent}}` - Percentage watched
|
|
- `{{Video Provider}}` - "youtube"
|
|
- `{{Video Visible}}` - true/false if video in viewport
|
|
|
|
**Supported Video Events:**
|
|
|
|
- **Start** - Video playback begins
|
|
- **Complete** - Video finishes
|
|
- **Pause** - User pauses video
|
|
- **Seeking** - User scrubs to different time
|
|
- **Buffering** - Video buffering
|
|
- **Progress** - Reaches progress thresholds
|
|
|
|
### Other Triggers
|
|
|
|
#### Custom Event
|
|
|
|
Fires when a specific custom event is pushed to the data layer.
|
|
|
|
**Event:** Custom event name from `dataLayer.push()`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track business events (purchase, signup, login)
|
|
- Track SPA (Single Page App) page views
|
|
- Track custom user interactions
|
|
- Integrate with custom application logic
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Custom Event
|
|
Event name: purchase
|
|
|
|
Use regex matching: ☐
|
|
|
|
This trigger fires on: All Custom Events
|
|
OR
|
|
This trigger fires on: Some Custom Events
|
|
{{Transaction Value}} greater than 100
|
|
```
|
|
|
|
**Data Layer Push:**
|
|
|
|
```javascript
|
|
// Push custom event to data layer
|
|
dataLayer.push({
|
|
'event': 'purchase',
|
|
'transactionId': 'T12345',
|
|
'transactionTotal': 99.99,
|
|
'transactionProducts': [
|
|
{
|
|
'sku': 'PROD-001',
|
|
'name': 'Product Name',
|
|
'price': 99.99,
|
|
'quantity': 1
|
|
}
|
|
]
|
|
});
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Custom Event - purchase
|
|
Type: Custom Event
|
|
Event name: purchase
|
|
Fires on: All Custom Events
|
|
Use: Fire conversion tags on purchase
|
|
```
|
|
|
|
```
|
|
Name: Custom Event - High Value Purchase
|
|
Type: Custom Event
|
|
Event name: purchase
|
|
Fires on: Some Custom Events
|
|
{{DLV - Transaction Total}} greater than 500
|
|
Use: Track high-value purchases separately
|
|
```
|
|
|
|
```
|
|
Name: Custom Event - Virtual Pageview
|
|
Type: Custom Event
|
|
Event name: virtualPageview
|
|
Use: Track SPA navigation
|
|
```
|
|
|
|
```
|
|
Name: Custom Event - User Login
|
|
Type: Custom Event
|
|
Event name: user_login
|
|
Fires on: Some Custom Events
|
|
{{DLV - User Type}} equals premium
|
|
Use: Track premium user logins
|
|
```
|
|
|
|
**Regex Matching:**
|
|
|
|
```
|
|
Event name: (purchase|transaction|order)
|
|
Use regex matching: ☑
|
|
|
|
Matches: purchase, transaction, or order events
|
|
```
|
|
|
|
**Best Practices:**
|
|
|
|
- Use consistent, descriptive event names
|
|
- Use snake_case naming: `user_signup`, `add_to_cart`
|
|
- Document all custom events
|
|
- Push event first in data layer object
|
|
|
|
#### Timer
|
|
|
|
Fires at specified time intervals.
|
|
|
|
**Event:** `gtm.timer`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track engaged time on page
|
|
- Send heartbeat events
|
|
- Track video watch time
|
|
- Measure time to conversion
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: Timer
|
|
Event Name: engagement_timer (custom name for this timer)
|
|
Interval: 30000 milliseconds (30 seconds)
|
|
Limit: 10 times
|
|
|
|
This trigger fires on: All Pages
|
|
OR
|
|
This trigger fires on: Some Pages
|
|
Page Path contains /article/
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: Timer - Engagement Heartbeat
|
|
Type: Timer
|
|
Event Name: engagement_timer
|
|
Interval: 30000 (30 seconds)
|
|
Limit: 20
|
|
Fires on: All Pages
|
|
Use: Track engaged time on site
|
|
```
|
|
|
|
```
|
|
Name: Timer - Article Reading Time
|
|
Type: Timer
|
|
Event Name: article_timer
|
|
Interval: 15000 (15 seconds)
|
|
Limit: 40
|
|
Fires on: Some Pages
|
|
Page Path starts with /blog/
|
|
OR Page Path starts with /articles/
|
|
Use: Measure article reading time
|
|
```
|
|
|
|
**Built-in Timer Variables:**
|
|
|
|
- `{{Timer Interval}}` - Configured interval (ms)
|
|
- `{{Event}}` - Will equal the Event Name you configured
|
|
|
|
**Calculating Elapsed Time:**
|
|
|
|
Combine with Custom JavaScript variable:
|
|
|
|
```javascript
|
|
function() {
|
|
var interval = {{Timer Interval}};
|
|
var limit = 20; // Your configured limit
|
|
|
|
// Calculate elapsed time
|
|
return interval * limit / 1000; // Returns seconds
|
|
}
|
|
```
|
|
|
|
**Settings:**
|
|
|
|
- **Event Name** - Custom name to identify this timer
|
|
- **Interval** - Time between fires (milliseconds)
|
|
- **Limit** - Max number of times to fire (blank = unlimited)
|
|
|
|
#### History Change
|
|
|
|
Fires when the URL changes without a full page reload (Single Page Applications).
|
|
|
|
**Event:** `gtm.historyChange`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track SPA (Single Page App) navigation
|
|
- Track AJAX page transitions
|
|
- Track URL hash changes
|
|
- Track pushState/replaceState events
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: History Change
|
|
|
|
This trigger fires on: All History Changes
|
|
OR
|
|
This trigger fires on: Some History Changes
|
|
Page Path contains /app/
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: History Change - SPA Navigation
|
|
Type: History Change
|
|
Fires on: All History Changes
|
|
Use: Track virtual pageviews in React/Vue/Angular apps
|
|
```
|
|
|
|
```
|
|
Name: History Change - App Section
|
|
Type: History Change
|
|
Fires on: Some History Changes
|
|
Page Path starts with /app/
|
|
AND Page Path does not contain /app/admin/
|
|
Use: Track navigation within app section
|
|
```
|
|
|
|
**When URLs Change:**
|
|
|
|
The trigger fires when:
|
|
- `history.pushState()` is called
|
|
- `history.replaceState()` is called
|
|
- Hash changes (`#section`)
|
|
- Back/forward browser navigation (within SPA)
|
|
|
|
**Common Implementation:**
|
|
|
|
```javascript
|
|
// In your SPA, after route change:
|
|
dataLayer.push({
|
|
'event': 'virtualPageview',
|
|
'pagePath': '/new-page',
|
|
'pageTitle': 'New Page Title'
|
|
});
|
|
```
|
|
|
|
**Built-in Variables:**
|
|
|
|
Standard page variables update automatically:
|
|
- `{{Page URL}}`
|
|
- `{{Page Path}}`
|
|
- `{{Page Hostname}}`
|
|
|
|
#### JavaScript Error
|
|
|
|
Fires when JavaScript errors occur on the page.
|
|
|
|
**Event:** `gtm.jsError`
|
|
|
|
**Common Use Cases:**
|
|
|
|
- Track JavaScript errors
|
|
- Monitor site health
|
|
- Debug issues in production
|
|
- Send errors to error tracking tools
|
|
|
|
**Configuration:**
|
|
|
|
```
|
|
Trigger Type: JavaScript Error
|
|
|
|
This trigger fires on: All Errors
|
|
OR
|
|
This trigger fires on: Some Errors
|
|
Error Message does not contain "Non-critical warning"
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
Name: JavaScript Error - All Errors
|
|
Type: JavaScript Error
|
|
Fires on: All Errors
|
|
Use: Track all JavaScript errors
|
|
```
|
|
|
|
```
|
|
Name: JavaScript Error - Critical Only
|
|
Type: JavaScript Error
|
|
Fires on: Some Errors
|
|
Error Message does not contain "Warning"
|
|
AND Error URL equals {{Page URL}}
|
|
Use: Track only critical errors from own code
|
|
```
|
|
|
|
**Built-in Error Variables:**
|
|
|
|
Enable Error variables:
|
|
- `{{Error Message}}` - The error message text
|
|
- `{{Error URL}}` - URL where error occurred
|
|
- `{{Error Line}}` - Line number in source file
|
|
- `{{Debug Mode}}` - true/false if GTM in debug mode
|
|
|
|
**Example Error Tracking Tag:**
|
|
|
|
```
|
|
Tag: GA4 - Event - JavaScript Error
|
|
Event Name: javascript_error
|
|
Event Parameters:
|
|
error_message: {{Error Message}}
|
|
error_url: {{Error URL}}
|
|
error_line: {{Error Line}}
|
|
page_url: {{Page URL}}
|
|
Trigger: JavaScript Error - All Errors
|
|
```
|
|
|
|
**Filtering Noise:**
|
|
|
|
Common errors to exclude:
|
|
|
|
```
|
|
Error Message does not contain "ResizeObserver loop limit exceeded"
|
|
Error Message does not contain "Script error."
|
|
Error Message does not contain "Non-Error promise rejection captured"
|
|
Error URL equals {{Page URL}} (exclude third-party script errors)
|
|
```
|
|
|
|
## Trigger Configuration
|
|
|
|
### Trigger Conditions and Filters
|
|
|
|
Triggers use conditions to determine when to fire. Conditions compare a variable to a value using an operator.
|
|
|
|
**Condition Structure:**
|
|
|
|
```
|
|
[Variable] [Operator] [Value]
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```
|
|
{{Page Path}} contains /checkout
|
|
```
|
|
|
|
### Filter Operators
|
|
|
|
#### String Operators
|
|
|
|
**equals**
|
|
- Exact match (case-sensitive)
|
|
- Example: `{{Click ID}} equals submit-btn`
|
|
|
|
**does not equal**
|
|
- Not an exact match
|
|
- Example: `{{Page Hostname}} does not equal localhost`
|
|
|
|
**contains**
|
|
- Value contains substring
|
|
- Example: `{{Page URL}} contains /product/`
|
|
|
|
**does not contain**
|
|
- Value doesn't contain substring
|
|
- Example: `{{Click URL}} does not contain example.com`
|
|
|
|
**starts with**
|
|
- Value begins with string
|
|
- Example: `{{Page Path}} starts with /blog/`
|
|
|
|
**ends with**
|
|
- Value ends with string
|
|
- Example: `{{Click URL}} ends with .pdf`
|
|
|
|
**matches RegEx**
|
|
- Value matches RE2 regular expression
|
|
- Example: `{{Page Path}} matches RegEx ^/category/\d+$`
|
|
- **IMPORTANT:** Uses RE2 format (see section above)
|
|
|
|
**matches RegEx (ignore case)**
|
|
- Case-insensitive regex match
|
|
- Example: `{{Click URL}} matches RegEx (ignore case) \.pdf$`
|
|
- Matches: .pdf, .PDF, .Pdf
|
|
|
|
#### Numeric Operators
|
|
|
|
**equals**
|
|
- Numeric equality
|
|
- Example: `{{DLV - Cart Items}} equals 3`
|
|
|
|
**does not equal**
|
|
- Numeric inequality
|
|
- Example: `{{Random Number}} does not equal 0`
|
|
|
|
**less than**
|
|
- Value < number
|
|
- Example: `{{DLV - Transaction Value}} less than 50`
|
|
|
|
**less than or equal to**
|
|
- Value <= number
|
|
- Example: `{{Scroll Depth Threshold}} less than or equal to 50`
|
|
|
|
**greater than**
|
|
- Value > number
|
|
- Example: `{{DLV - Product Price}} greater than 100`
|
|
|
|
**greater than or equal to**
|
|
- Value >= number
|
|
- Example: `{{Video Percent}} greater than or equal to 75`
|
|
|
|
#### Boolean Operators
|
|
|
|
**is true**
|
|
- Variable evaluates to true
|
|
- Example: `{{Cookie - user_logged_in}} is true`
|
|
|
|
**is false**
|
|
- Variable evaluates to false
|
|
- Example: `{{Cookie - consent_given}} is false`
|
|
|
|
#### Existence Operators
|
|
|
|
**is defined**
|
|
- Variable has a value (not undefined/null)
|
|
- Example: `{{DLV - User ID}} is defined`
|
|
|
|
**is not defined**
|
|
- Variable is undefined/null/empty
|
|
- Example: `{{Cookie - returning_visitor}} is not defined`
|
|
|
|
### Using RE2 Regex in Triggers
|
|
|
|
Regular expressions enable powerful pattern matching in triggers.
|
|
|
|
**URL Matching Examples:**
|
|
|
|
```
|
|
# Match checkout pages
|
|
{{Page Path}} matches RegEx: ^/checkout
|
|
|
|
# Match product pages with SKU
|
|
{{Page Path}} matches RegEx: ^/product/[A-Z0-9-]+$
|
|
|
|
# Match blog posts with date structure
|
|
{{Page URL}} matches RegEx: /blog/\d{4}/\d{2}/\d{2}/
|
|
|
|
# Match any subdomain
|
|
{{Page Hostname}} matches RegEx: ^[^.]+\.example\.com$
|
|
|
|
# Match query parameter presence
|
|
{{Page URL}} matches RegEx: [?&]utm_source=
|
|
|
|
# Match multiple page types
|
|
{{Page Path}} matches RegEx: ^/(checkout|cart|payment)
|
|
```
|
|
|
|
**Click URL Matching:**
|
|
|
|
```
|
|
# External links (not your domain)
|
|
{{Click URL}} matches RegEx: ^https?://(?!example\.com)
|
|
|
|
# File downloads
|
|
{{Click URL}} matches RegEx: \.(pdf|docx?|xlsx?|zip|csv)(\?|$)
|
|
|
|
# Email links
|
|
{{Click URL}} matches RegEx: ^mailto:[\w.+-]+@[\w.-]+\.\w{2,}$
|
|
|
|
# Phone links
|
|
{{Click URL}} matches RegEx: ^tel:\+?[\d\s\-()]+$
|
|
|
|
# Anchor links (same page)
|
|
{{Click URL}} matches RegEx: ^#[^/]
|
|
```
|
|
|
|
**Element ID/Class Matching:**
|
|
|
|
```
|
|
# Button IDs starting with "btn-"
|
|
{{Click ID}} matches RegEx: ^btn-
|
|
|
|
# Classes containing "cta" or "call-to-action"
|
|
{{Click Classes}} matches RegEx: (cta|call-to-action)
|
|
|
|
# Form IDs matching pattern
|
|
{{Form ID}} matches RegEx: ^(contact|signup|newsletter)-form$
|
|
```
|
|
|
|
**Text Content Matching:**
|
|
|
|
```
|
|
# Case-insensitive "buy now" or "purchase"
|
|
{{Click Text}} matches RegEx (ignore case): (buy now|purchase)
|
|
|
|
# Numbers in click text
|
|
{{Click Text}} matches RegEx: \d+
|
|
|
|
# Specific patterns
|
|
{{Click Text}} matches RegEx: ^(Sign Up|Subscribe|Join)$
|
|
```
|
|
|
|
**Common Regex Patterns:**
|
|
|
|
```regex
|
|
# Match digits
|
|
\d+
|
|
|
|
# Match word characters
|
|
\w+
|
|
|
|
# Match optional whitespace
|
|
\s*
|
|
|
|
# Match URL path segment
|
|
/[\w-]+
|
|
|
|
# Match query parameter
|
|
[?&]param=([^&]+)
|
|
|
|
# Match file extension
|
|
\.(ext1|ext2|ext3)$
|
|
|
|
# Case-insensitive
|
|
(?i)pattern
|
|
|
|
# Start of string
|
|
^pattern
|
|
|
|
# End of string
|
|
pattern$
|
|
|
|
# Optional group
|
|
(pattern)?
|
|
|
|
# Multiple occurrences
|
|
pattern{2,5}
|
|
```
|
|
|
|
### Multiple Conditions (AND/OR Logic)
|
|
|
|
**AND Logic (within a trigger):**
|
|
|
|
All conditions must match:
|
|
|
|
```
|
|
Trigger: Pageview - Product Category Pages
|
|
Type: Page View
|
|
Fires on: Some Page Views
|
|
{{Page Path}} starts with /category/
|
|
AND {{Page Path}} does not contain /admin/
|
|
AND {{Cookie - user_type}} equals customer
|
|
```
|
|
|
|
All three conditions must be true.
|
|
|
|
**OR Logic (multiple triggers):**
|
|
|
|
Create separate triggers for OR logic:
|
|
|
|
```
|
|
Tag: GA4 - Event - Conversion
|
|
|
|
Firing Triggers:
|
|
- Custom Event - purchase
|
|
- Custom Event - transaction
|
|
- Custom Event - order_complete
|
|
|
|
Tag fires if ANY trigger matches (OR logic)
|
|
```
|
|
|
|
**Complex Logic:**
|
|
|
|
Combine AND within triggers, OR across triggers:
|
|
|
|
```
|
|
Trigger 1: High Value Purchase
|
|
{{Custom Event}} equals purchase
|
|
AND {{DLV - Transaction Value}} greater than 500
|
|
|
|
Trigger 2: Premium User Purchase
|
|
{{Custom Event}} equals purchase
|
|
AND {{DLV - User Type}} equals premium
|
|
|
|
Tag fires on: (Trigger 1) OR (Trigger 2)
|
|
```
|
|
|
|
### Built-in Variables for Triggers
|
|
|
|
Enable built-in variables in Variables → Configure:
|
|
|
|
**Page Variables:**
|
|
- `{{Page URL}}` - Full page URL
|
|
- `{{Page Hostname}}` - example.com
|
|
- `{{Page Path}}` - /category/products
|
|
- `{{Referrer}}` - Previous page URL
|
|
|
|
**Click Variables:**
|
|
- `{{Click Element}}` - Clicked DOM element
|
|
- `{{Click Classes}}` - Element CSS classes
|
|
- `{{Click ID}}` - Element ID
|
|
- `{{Click URL}}` - Link href
|
|
- `{{Click Text}}` - Element text content
|
|
|
|
**Form Variables:**
|
|
- `{{Form Element}}` - Form DOM element
|
|
- `{{Form Classes}}` - Form CSS classes
|
|
- `{{Form ID}}` - Form ID
|
|
- `{{Form URL}}` - Form action URL
|
|
- `{{Form Text}}` - Form text content
|
|
|
|
**Utility Variables:**
|
|
- `{{Container ID}}` - GTM container ID
|
|
- `{{Random Number}}` - Random 0-2147483647
|
|
- `{{Environment Name}}` - Live/Preview/Latest
|
|
|
|
## Advanced Trigger Concepts
|
|
|
|
### Trigger Groups
|
|
|
|
Combine multiple triggers to create complex firing logic.
|
|
|
|
**Trigger Group:**
|
|
|
|
Create a trigger group in GTM interface to:
|
|
- Require ALL triggers in group (AND logic across triggers)
|
|
- Simplify complex conditions
|
|
|
|
**Use Case:**
|
|
|
|
Fire tag only when user is logged in AND on checkout page AND cart value > $50
|
|
|
|
### Trigger Firing Limits
|
|
|
|
Some triggers support limits:
|
|
|
|
**Timer Trigger:**
|
|
- Limit: Maximum number of times to fire
|
|
|
|
**Element Visibility:**
|
|
- Once per page
|
|
- Once per element
|
|
- Every time element appears
|
|
|
|
### Auto-Event Variables
|
|
|
|
Many triggers create auto-event variables:
|
|
|
|
**Click Triggers:**
|
|
- Automatically populate Click variables
|
|
|
|
**Form Triggers:**
|
|
- Automatically populate Form variables
|
|
|
|
**Video Triggers:**
|
|
- Automatically populate Video variables
|
|
|
|
**Scroll Triggers:**
|
|
- Automatically populate Scroll variables
|
|
|
|
Enable these in Variables → Configure Built-In Variables.
|
|
|
|
### Event Callbacks
|
|
|
|
Execute code after tag fires using `eventCallback`:
|
|
|
|
```javascript
|
|
dataLayer.push({
|
|
'event': 'purchase',
|
|
'transactionId': 'T12345',
|
|
'eventCallback': function() {
|
|
// Execute after tags fire
|
|
console.log('Purchase tags fired');
|
|
// Redirect user
|
|
window.location.href = '/thank-you';
|
|
},
|
|
'eventTimeout': 2000
|
|
});
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### Trigger Naming Conventions
|
|
|
|
Use consistent, descriptive naming:
|
|
|
|
```
|
|
[Type] - [Condition] - [Description]
|
|
```
|
|
|
|
**Examples:**
|
|
|
|
- `Pageview - All Pages`
|
|
- `Pageview - Product Pages`
|
|
- `Click - CTA Buttons`
|
|
- `Click - External Links`
|
|
- `Custom Event - purchase`
|
|
- `Form Submit - Contact Form`
|
|
- `Scroll Depth - Blog Posts`
|
|
- `Timer - Engagement Tracking`
|
|
|
|
### Testing Triggers
|
|
|
|
**Preview Mode:**
|
|
|
|
1. Enable Preview in GTM
|
|
2. Navigate to test page
|
|
3. Perform action (click, scroll, etc.)
|
|
4. Check "Tags Fired" in debug panel
|
|
5. Verify trigger conditions in debug panel
|
|
|
|
**Debug Checklist:**
|
|
|
|
- [ ] Trigger fires at correct time
|
|
- [ ] All conditions evaluate correctly
|
|
- [ ] Variables populate with expected values
|
|
- [ ] No false positives (unwanted firing)
|
|
- [ ] No false negatives (should fire but doesn't)
|
|
|
|
### Debugging Trigger Issues
|
|
|
|
**Trigger Not Firing:**
|
|
|
|
1. Check trigger conditions - are they too restrictive?
|
|
2. Verify built-in variables are enabled
|
|
3. Check data layer for custom events
|
|
4. Review trigger type matches event
|
|
5. Check for blocking triggers on tag
|
|
|
|
**Trigger Firing Too Often:**
|
|
|
|
1. Add more specific conditions
|
|
2. Use "Once per page/element" for visibility triggers
|
|
3. Add filters to exclude unwanted pages
|
|
4. Check for duplicate triggers
|
|
|
|
**Variables Not Populating:**
|
|
|
|
1. Enable built-in variables in Variables section
|
|
2. Check variable names match exactly (case-sensitive)
|
|
3. Verify data layer structure for DLV
|
|
4. Check timing - is data available when trigger fires?
|
|
|
|
### Performance Considerations
|
|
|
|
**Minimize Click Listeners:**
|
|
|
|
- Use "Just Links" for link tracking (more efficient than "All Elements")
|
|
- Add specific conditions to reduce evaluation overhead
|
|
- Don't track all clicks indiscriminately
|
|
|
|
**Optimize Scroll Depth:**
|
|
|
|
- Limit scroll thresholds (5-7 maximum)
|
|
- Only enable on relevant pages
|
|
- Use percentages for responsive design
|
|
|
|
**Timer Triggers:**
|
|
|
|
- Use reasonable intervals (not < 5 seconds)
|
|
- Set limits to prevent infinite firing
|
|
- Only enable on necessary pages
|
|
|
|
**Element Visibility:**
|
|
|
|
- Use specific selectors (ID preferred over class)
|
|
- Enable "Observe DOM changes" only when needed
|
|
- Limit to relevant pages
|
|
|
|
## Resources
|
|
|
|
### Official Documentation
|
|
|
|
- [GTM Triggers Overview](https://support.google.com/tagmanager/topic/7679108)
|
|
- [Trigger Types Reference](https://support.google.com/tagmanager/answer/7679319)
|
|
- [Auto-Event Variables](https://support.google.com/tagmanager/answer/7679316)
|
|
- [RE2 Syntax Reference](https://github.com/google/re2/wiki/Syntax)
|
|
|
|
### Related GTM Skills
|
|
|
|
- [GTM Tags](./tags.md) - Comprehensive tag documentation
|
|
- [GTM Variables](./variables.md) - Variable types and configuration
|
|
- [GTM Data Layer](../../gtm-datalayer/gtm-datalayer/references/datalayer-fundamentals.md) - Data layer implementation
|
|
- [GTM Best Practices](./best-practices.md) - Naming, organization, regex usage
|
|
|
|
### Tools
|
|
|
|
- [Regex101](https://regex101.com/) - Test regex patterns (select "Golang" for RE2)
|
|
- [GTM Preview Mode](https://support.google.com/tagmanager/answer/6107056)
|
|
- [Google Tag Assistant](https://tagassistant.google.com/)
|
|
|
|
### Community
|
|
|
|
- [GTM Community Forum](https://support.google.com/tagmanager/community)
|
|
- [Simo Ahava's Blog](https://www.simoahava.com/)
|
|
- [Analytics Mania](https://www.analyticsmania.com/)
|
|
- [MeasureSchool](https://measureschool.com/)
|