Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:32:40 +08:00
commit 0ea8352871
72 changed files with 30043 additions and 0 deletions

View File

@@ -0,0 +1,230 @@
---
name: ga4-gtm-integration
description: Expert guidance for implementing GA4 using Google Tag Manager including configuration tags, event tags, triggers, variables, and data layer integration. Use when setting up GA4 in GTM, creating GA4 event tags, configuring GTM triggers for GA4, working with GTM data layer for GA4 events, or debugging GTM-GA4 implementation. Covers GTM container setup, Google Tag configuration, Preview mode, and GTM best practices for GA4.
---
# GA4 Google Tag Manager Integration
## Overview
Google Tag Manager (GTM) provides a powerful, no-code approach to implementing Google Analytics 4 tracking. This skill covers complete GTM-GA4 integration, from initial configuration tags to advanced event tracking with data layer integration.
## When to Use This Skill
Invoke this skill when:
- Setting up GA4 tracking through Google Tag Manager
- Creating GA4 Configuration tags (base tracking)
- Building GA4 event tags for specific user actions
- Configuring triggers for GA4 events (clicks, forms, custom events)
- Implementing dataLayer.push() for custom event tracking
- Using GTM Preview mode for testing GA4 implementation
- Debugging GTM-GA4 tag firing issues
- Working with GTM container files (.json) for GA4
- Managing GA4 tracking without code changes to website
- Migrating from gtag.js to GTM implementation
## Core Capabilities
### GTM-GA4 Setup Fundamentals
**GA4 Configuration Tag (Base Tag)**
The GA4 Configuration tag initializes GA4 on all pages. Create this first:
1. **Tag Type:** Google Tag (formerly GA4 Configuration)
2. **Tag ID:** GA4 Measurement ID (G-XXXXXXXXXX)
3. **Trigger:** Initialization - All Pages
4. **Configuration Settings:** Optional global parameters
5. **Shared Event Settings:** Parameters sent with every event
**Key Configuration Options:**
- Allow Google Signals
- Allow ad personalization signals
- Send page view automatically (default: true)
- User ID (if using cross-device tracking)
- Custom user properties
### Creating GA4 Event Tags
**Event Tag Structure:**
1. **Tag Configuration:** Google Tag
2. **Tag ID:** Same GA4 Measurement ID
3. **Event Name:** Specific event (e.g., "button_click", "form_submit")
4. **Event Parameters:** Additional data for the event
5. **Triggering:** Specific trigger for when event fires
**Common Event Tag Examples:**
**Button Click Event:**
- Event Name: `button_click`
- Parameters: `button_name`, `button_location`, `button_id`
- Trigger: Click - All Elements (filter by button ID/class)
**Form Submission Event:**
- Event Name: `form_submit`
- Parameters: `form_name`, `form_id`, `form_destination`
- Trigger: Form Submission (filter by form ID)
**Purchase Event:**
- Event Name: `purchase`
- Parameters: `transaction_id`, `value`, `currency`, `items`
- Trigger: Custom Event (`dataLayer.push({event: 'purchase'})`)
### GTM Triggers for GA4
**Trigger Types for GA4 Events:**
**Page View Triggers:**
- All Pages
- Some Pages (filtered by URL, page path)
- DOM Ready
- Window Loaded
**Click Triggers:**
- All Elements
- Just Links
- Filter by Click ID, Class, URL, Text
**Form Triggers:**
- Form Submission
- Filter by Form ID, Class, URL
**Custom Event Triggers:**
- Custom Event name from dataLayer
- Example: `event: 'add_to_cart'`
**JavaScript Error:**
- Error Message tracking
**Scroll Depth:**
- Vertical Scroll Percentage
### GTM Variables for GA4
**Built-in Variables (Enable in Variables section):**
**Page Variables:**
- Page URL
- Page Hostname
- Page Path
- Referrer
**Click Variables:**
- Click Element
- Click Classes
- Click ID
- Click Text
- Click URL
**Form Variables:**
- Form Element
- Form Classes
- Form ID
- Form Text
**Data Layer Variables:**
Create variables to extract data from `dataLayer`:
**Variable Type:** Data Layer Variable
**Data Layer Variable Name:** Exact key name (e.g., `product_id`, `user_tier`)
**Usage:** Reference in event parameters as `{{DL - Product ID}}`
### Data Layer Integration
**What is the Data Layer?**
JavaScript object that holds structured data for GTM to access:
```javascript
window.dataLayer = window.dataLayer || [];
```
**Pushing Events to Data Layer:**
```javascript
dataLayer.push({
'event': 'add_to_cart',
'product_id': 'SKU_123',
'product_name': 'Blue T-Shirt',
'price': 29.99,
'quantity': 1
});
```
**GTM listens for the `event` key** and fires corresponding Custom Event triggers.
**Event Parameters from Data Layer:**
In GTM event tag, map Data Layer Variables to event parameters:
- Parameter Name: `product_id`
- Value: `{{DL - Product ID}}`
### Testing with GTM Preview Mode
**Workflow:**
1. Click **Preview** in GTM workspace
2. Connect to website
3. **Tag Assistant** opens showing real-time tag activity
4. Interact with website elements
5. View in Tag Assistant:
- Events fired
- Tags triggered
- Variables populated
- Parameters sent to GA4
**Verification Checklist:**
- GA4 Configuration tag fires on all pages (Initialization trigger)
- Event tags fire when expected (correct triggers)
- Event names appear correctly
- Event parameters match Data Layer
- No duplicate tag firing
- Variables populate with correct values
### Publishing GTM Container
**Steps:**
1. Click **Submit** (top-right)
2. Enter **Version Name** (e.g., "GA4 Setup - November 2024")
3. Enter **Version Description** (what changed)
4. Click **Publish**
5. Changes go live immediately
## Integration with Other Skills
- **ga4-setup** - Initial GA4 property and data stream setup prerequisite
- **ga4-gtag-implementation** - Alternative implementation method without GTM
- **ga4-recommended-events** - Implementing specific Google-recommended events via GTM
- **ga4-custom-events** - Creating custom event tags for business-specific tracking
- **ga4-debugview** - Testing GTM implementation with GA4 DebugView
- **gtm-configuration** - General GTM tag/trigger/variable knowledge
- **gtm-datalayer** - Advanced data layer implementation patterns
## References
- **references/gtm-ga4-setup-complete.md** - Complete step-by-step GTM-GA4 setup walkthrough
- **references/gtm-tags-triggers-variables.md** - Comprehensive tag, trigger, and variable reference for GA4
- **references/gtm-data-layer-ga4.md** - Data layer implementation patterns for GA4 events
- **references/gtm-preview-debugging.md** - GTM Preview mode usage and troubleshooting
- **references/gtm-best-practices-ga4.md** - GTM-specific best practices for GA4 implementation
## Quick Reference
**GTM-GA4 Setup Order:**
1. Create GA4 Configuration tag (Initialization trigger)
2. Test with Preview mode
3. Create event tags for specific tracking
4. Create triggers for events
5. Create data layer variables (if needed)
6. Test with Preview mode
7. Publish container
**Common Issues:**
- **Tags not firing:** Check trigger conditions in Preview mode
- **Wrong parameter values:** Verify Data Layer Variable mapping
- **Duplicate events:** Remove duplicate GTM tags or gtag() calls
- **Measurement ID not recognized:** Copy exact ID from GA4 Data Streams

View File

@@ -0,0 +1,272 @@
{
"exportFormatVersion": 2,
"exportTime": "2025-11-10 04:00:00",
"containerVersion": {
"path": "accounts/ACCOUNT_ID/containers/CONTAINER_ID/versions/VERSION_ID",
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"containerVersionId": "VERSION_ID",
"name": "GA4 Starter Configuration",
"description": "Basic GA4 tracking setup with Configuration tag, page view, and common event examples",
"container": {
"path": "accounts/ACCOUNT_ID/containers/CONTAINER_ID",
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"name": "GA4 Starter Container",
"publicId": "GTM-XXXXXXX",
"usageContext": ["WEB"],
"fingerprint": "0000000000000",
"tagManagerUrl": "https://tagmanager.google.com/#/container/accounts/ACCOUNT_ID/containers/CONTAINER_ID/workspaces/WORKSPACE_ID"
},
"tag": [
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"tagId": "1",
"name": "GA4 - Configuration",
"type": "googtag",
"parameter": [
{
"type": "TEMPLATE",
"key": "tagId",
"value": "G-XXXXXXXXXX"
}
],
"firingTriggerId": ["2147479553"],
"tagFiringOption": "ONCE_PER_EVENT",
"monitoringMetadata": {
"type": "MAP"
}
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"tagId": "2",
"name": "GA4 - Button Click - Subscribe",
"type": "googtag",
"parameter": [
{
"type": "TEMPLATE",
"key": "tagId",
"value": "G-XXXXXXXXXX"
},
{
"type": "TEMPLATE",
"key": "eventName",
"value": "button_click"
},
{
"type": "LIST",
"key": "eventParameters",
"list": [
{
"type": "MAP",
"map": [
{
"type": "TEMPLATE",
"key": "name",
"value": "button_name"
},
{
"type": "TEMPLATE",
"key": "value",
"value": "{{Click Text}}"
}
]
},
{
"type": "MAP",
"map": [
{
"type": "TEMPLATE",
"key": "name",
"value": "button_location"
},
{
"type": "TEMPLATE",
"key": "value",
"value": "header"
}
]
}
]
}
],
"firingTriggerId": ["3"],
"tagFiringOption": "ONCE_PER_EVENT"
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"tagId": "4",
"name": "GA4 - Form Submit - Contact",
"type": "googtag",
"parameter": [
{
"type": "TEMPLATE",
"key": "tagId",
"value": "G-XXXXXXXXXX"
},
{
"type": "TEMPLATE",
"key": "eventName",
"value": "form_submit"
},
{
"type": "LIST",
"key": "eventParameters",
"list": [
{
"type": "MAP",
"map": [
{
"type": "TEMPLATE",
"key": "name",
"value": "form_name"
},
{
"type": "TEMPLATE",
"key": "value",
"value": "contact_form"
}
]
},
{
"type": "MAP",
"map": [
{
"type": "TEMPLATE",
"key": "name",
"value": "form_id"
},
{
"type": "TEMPLATE",
"key": "value",
"value": "{{Form ID}}"
}
]
}
]
}
],
"firingTriggerId": ["5"],
"tagFiringOption": "ONCE_PER_EVENT"
}
],
"trigger": [
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"triggerId": "3",
"name": "Click - Subscribe Button",
"type": "CLICK",
"filter": [
{
"type": "EQUALS",
"parameter": [
{
"type": "TEMPLATE",
"key": "arg0",
"value": "{{Click ID}}"
},
{
"type": "TEMPLATE",
"key": "arg1",
"value": "subscribe-btn"
}
]
}
]
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"triggerId": "5",
"name": "Form - Contact Form Submit",
"type": "FORM_SUBMIT",
"filter": [
{
"type": "EQUALS",
"parameter": [
{
"type": "TEMPLATE",
"key": "arg0",
"value": "{{Form ID}}"
},
{
"type": "TEMPLATE",
"key": "arg1",
"value": "contact-form"
}
]
}
]
}
],
"variable": [
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"variableId": "6",
"name": "DL - Product ID",
"type": "v",
"parameter": [
{
"type": "INTEGER",
"key": "dataLayerVersion",
"value": "2"
},
{
"type": "BOOLEAN",
"key": "setDefaultValue",
"value": "false"
},
{
"type": "TEMPLATE",
"key": "name",
"value": "product_id"
}
]
}
],
"builtInVariable": [
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"type": "PAGE_URL",
"name": "Page URL"
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"type": "PAGE_PATH",
"name": "Page Path"
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"type": "CLICK_ELEMENT",
"name": "Click Element"
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"type": "CLICK_TEXT",
"name": "Click Text"
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"type": "CLICK_ID",
"name": "Click ID"
},
{
"accountId": "ACCOUNT_ID",
"containerId": "CONTAINER_ID",
"type": "FORM_ID",
"name": "Form ID"
}
],
"fingerprint": "0000000000001"
}
}

View File

@@ -0,0 +1,380 @@
# GTM Best Practices for GA4 Implementation
## Container Organization
### Naming Conventions
**Tags:**
- `GA4 - Configuration` (base tag)
- `GA4 - [Event Name] - [Description]`
- Examples:
- `GA4 - Button Click - Subscribe`
- `GA4 - Form Submit - Contact`
- `GA4 - Purchase`
**Triggers:**
- `[Type] - [Description]`
- Examples:
- `All Pages`
- `Click - Subscribe Button`
- `Form - Contact Submit`
- `Custom Event - add_to_cart`
**Variables:**
- `DL - [Name]` for Data Layer Variables
- `JS - [Name]` for JavaScript Variables
- `Cookie - [Name]` for Cookies
- Examples:
- `DL - Product ID`
- `JS - User Tier`
- `Cookie - Session ID`
### Folder Structure
**Organize by Function:**
```
Folders:
├── GA4 - Core (Configuration tag)
├── GA4 - E-commerce (Purchase, add_to_cart, etc.)
├── GA4 - Engagement (Scroll, clicks, video)
├── GA4 - Forms
└── Variables - Data Layer
```
## Performance Optimization
### Rule 1: Use One GA4 Configuration Tag
**CORRECT:**
- One GA4 Configuration tag
- Fires on Initialization - All Pages
- Multiple event tags reference same Measurement ID
**WRONG:**
- Multiple GA4 Configuration tags
- Different Measurement IDs in same container
### Rule 2: Minimize Data Layer Pushes
**CORRECT:**
```javascript
dataLayer.push({
'event': 'add_to_cart',
'product_id': 'SKU_123',
'product_name': 'Blue T-Shirt',
'price': 29.99
});
```
**WRONG:**
```javascript
dataLayer.push({'event': 'add_to_cart'});
dataLayer.push({'product_id': 'SKU_123'});
dataLayer.push({'product_name': 'Blue T-Shirt'});
dataLayer.push({'price': 29.99});
```
### Rule 3: Use Specific Triggers
**CORRECT:**
```
Trigger Type: Click - All Elements
Fires on: Some Clicks
Condition: Click ID equals subscribe-btn
```
**WRONG:**
```
Trigger Type: Click - All Elements
Fires on: All Clicks
(Then filter in tag)
```
### Rule 4: Batch Event Parameters
**CORRECT:**
- Add all parameters in single event tag
- Use data layer variables efficiently
**WRONG:**
- Multiple tags for same event
- Separate pushes for each parameter
## Data Quality
### Use Consistent Event Names
**Best Practice:**
- Follow GA4 recommended event names
- Use snake_case consistently
- Document custom events
**Recommended Events:**
- `purchase`, `add_to_cart`, `begin_checkout`
- `sign_up`, `login`, `generate_lead`
- `view_item`, `view_item_list`, `select_item`
**Custom Events:**
- `button_click`, `form_submit`, `video_start`
- Keep lowercase with underscores
- Limit to 40 characters
### Validate Data Types
**Correct Types:**
- **String:** Event names, IDs, categories
- **Number:** Values, prices, quantities, revenue
- **Boolean:** true/false (not "true"/"false")
- **Array:** Items array for e-commerce
**Example:**
```javascript
dataLayer.push({
'event': 'purchase',
'transaction_id': 'T_12345', // String
'value': 99.99, // Number
'currency': 'USD', // String
'items': [...] // Array
});
```
### Avoid PII (Personally Identifiable Information)
**DO NOT Track:**
- Email addresses
- Phone numbers
- Full names
- Street addresses
- Social Security numbers
**Safe to Track:**
- Email domain (`@gmail.com`, `@company.com`)
- User IDs (hashed/anonymized)
- City/region (not specific addresses)
## Testing and QA
### Pre-Publication Checklist
- [ ] All tags fire in Preview mode
- [ ] Variables populate correctly
- [ ] Event names follow naming conventions
- [ ] Parameters have correct data types
- [ ] No PII in parameters
- [ ] Events appear in GA4 DebugView
- [ ] No duplicate events
- [ ] Data layer formatted correctly
- [ ] Documentation updated
- [ ] Version description written
### Version Control
**Every Publish:**
1. **Version Name:** Descriptive (e.g., "GA4 E-commerce Tracking - Nov 2024")
2. **Version Description:** Detailed list of changes
3. **Workspace Name:** Feature/task description
**Example Version Description:**
```
Changes:
- Added GA4 purchase event tracking
- Created data layer variables for transaction data
- Added form submission tracking for contact form
- Fixed duplicate page_view issue
Tested:
- Purchase flow (3 test transactions)
- Contact form submission
- All pages for duplicate events
```
### Rollback Plan
**If Issues After Publishing:**
1. Go to **Versions** tab
2. Find previous working version
3. Click **"•••"** → **Publish**
4. Confirm rollback
**Prevention:**
- Test thoroughly before publishing
- Publish during low-traffic periods
- Monitor for 30+ minutes after publishing
## Security and Privacy
### Use Appropriate Consent Mode
**Implementation:**
```javascript
// Set default consent state
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied'
});
// Update after user consent
gtag('consent', 'update', {
'ad_storage': 'granted',
'analytics_storage': 'granted'
});
```
### IP Anonymization
**Not Needed for GA4:**
- GA4 does not log or store IP addresses by default
- No `anonymize_ip` parameter needed
### Data Retention Settings
**In GA4:**
1. Admin → Data Settings → Data Retention
2. Set event data retention (2 or 14 months)
3. Enable/disable "Reset user data on new activity"
## Maintenance
### Regular Audits
**Monthly:**
- Review Tags Not Fired section
- Check for broken triggers
- Verify variables still working
- Test critical paths
**Quarterly:**
- Full container audit
- Remove unused tags/triggers/variables
- Update documentation
- Review naming conventions
**Annually:**
- Major cleanup
- Archive old tags
- Update to latest GA4 features
### Documentation
**Maintain Documentation For:**
- All custom events and parameters
- Data layer structure
- Trigger logic
- Variable mappings
- Change history
**Example Documentation:**
```markdown
# Custom Events
## add_to_cart
Fires when: User clicks "Add to Cart" button
Parameters:
- product_id (string): SKU
- product_name (string): Product name
- price (number): Unit price
- quantity (number): Quantity added
Data Layer: dataLayer.push({event: 'add_to_cart', ...})
GTM Tag: GA4 - Add to Cart
Trigger: Custom Event - add_to_cart
```
## Common Pitfalls to Avoid
### Pitfall 1: Multiple Measurement IDs
**Issue:** Using different Measurement IDs in event tags
**Solution:** Use same Measurement ID across all GA4 tags
### Pitfall 2: Not Clearing ecommerce Object
**Issue:** Old ecommerce data persists across events
**Solution:** Clear before each ecommerce push
```javascript
dataLayer.push({ ecommerce: null });
dataLayer.push({ event: 'purchase', ecommerce: {...} });
```
### Pitfall 3: Tracking PII
**Issue:** Accidentally sending email addresses or names
**Solution:** Review all data layer pushes and parameters
### Pitfall 4: Inconsistent Event Names
**Issue:** `buttonClick`, `button_click`, `Button_Click`
**Solution:** Use lowercase with underscores consistently
### Pitfall 5: Publishing Without Testing
**Issue:** Broken tags go live
**Solution:** Always use Preview mode before publishing
### Pitfall 6: No Version Descriptions
**Issue:** Can't identify what changed in version history
**Solution:** Write detailed version descriptions
### Pitfall 7: Overcomplicating Setup
**Issue:** Too many tags for simple tracking
**Solution:** Start simple, add complexity as needed
## Migration from gtag.js to GTM
**Steps:**
1. **Remove gtag.js snippet** from website
2. **Install GTM container** code
3. **Create GA4 Configuration tag** in GTM
4. **Migrate custom events** to GTM event tags
5. **Test thoroughly** in Preview mode
6. **Publish** GTM container
**Benefits:**
- No code changes needed for new tracking
- Easier testing with Preview mode
- Centralized tag management
- Better collaboration
## Collaboration Best Practices
### Workspaces
**Use Workspaces For:**
- Feature development
- Testing major changes
- Team collaboration
**Best Practices:**
- One workspace per feature/task
- Descriptive workspace names
- Merge/publish when complete
### User Permissions
**Roles:**
- **No Access:** No access to container
- **Read:** View-only access
- **Edit:** Create/modify tags (can't publish)
- **Approve:** Publish changes
- **Publish:** Full control
**Best Practice:**
- Limit Publish access
- Most users: Edit access
- Senior team: Approve/Publish
### Change Management
**Process:**
1. Create workspace for change
2. Implement and test
3. Submit for review (if applicable)
4. Peer review changes
5. Final testing in Preview
6. Publish with detailed description
7. Monitor for 30+ minutes

View File

@@ -0,0 +1,479 @@
# GTM Data Layer Implementation for GA4
## Data Layer Fundamentals
The **data layer** is a JavaScript object that acts as a bridge between your website and Google Tag Manager, holding structured data that GTM can access and send to GA4.
### Data Layer Structure
```javascript
window.dataLayer = window.dataLayer || [];
```
**Key Concepts:**
- Global JavaScript array
- Holds events and data
- GTM reads from this automatically
- Must exist BEFORE GTM container code
### Basic Data Layer Push
```javascript
dataLayer.push({
'event': 'event_name',
'parameter_key': 'parameter_value'
});
```
**Components:**
- `event`: Trigger name for GTM Custom Event triggers
- Additional keys: Data accessible via Data Layer Variables
## Event Tracking Patterns
### Pattern 1: Simple Event
**On Website:**
```javascript
dataLayer.push({
'event': 'button_click',
'button_name': 'Subscribe Now',
'button_location': 'header'
});
```
**In GTM:**
1. Create Trigger:
- Type: Custom Event
- Event name: `button_click`
2. Create Variables:
- Name: "DL - Button Name"
- Type: Data Layer Variable
- Variable Name: `button_name`
3. Create GA4 Tag:
- Event Name: `button_click`
- Parameters: `button_name``{{DL - Button Name}}`
### Pattern 2: E-commerce Event
**On Website:**
```javascript
dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {
'items': [
{
'item_id': 'SKU_123',
'item_name': 'Blue T-Shirt',
'price': 29.99,
'quantity': 1,
'item_category': 'Apparel'
}
],
'value': 29.99,
'currency': 'USD'
}
});
```
**In GTM:**
1. Create Variable for items:
- Name: "DL - Ecommerce Items"
- Type: Data Layer Variable
- Variable Name: `ecommerce.items`
2. Create GA4 Event Tag:
- Event Name: `add_to_cart`
- Parameters:
- `items``{{DL - Ecommerce Items}}`
- `value``{{DL - Ecommerce Value}}`
- `currency``{{DL - Ecommerce Currency}}`
### Pattern 3: Purchase Event (Complete)
**On Website:**
```javascript
dataLayer.push({
'event': 'purchase',
'ecommerce': {
'transaction_id': 'T_12345',
'affiliation': 'Online Store',
'value': 99.98,
'currency': 'USD',
'tax': 8.00,
'shipping': 5.00,
'coupon': 'SUMMER20',
'items': [
{
'item_id': 'SKU_123',
'item_name': 'Blue T-Shirt',
'price': 29.99,
'quantity': 2,
'item_category': 'Apparel',
'item_brand': 'MyBrand'
},
{
'item_id': 'SKU_124',
'item_name': 'Black Hat',
'price': 20.00,
'quantity': 2,
'item_category': 'Accessories'
}
]
}
});
```
**In GTM:**
Create Data Layer Variables for:
- `ecommerce.transaction_id`
- `ecommerce.value`
- `ecommerce.currency`
- `ecommerce.tax`
- `ecommerce.shipping`
- `ecommerce.items`
Create GA4 Event Tag mapping all parameters.
### Pattern 4: Form Submission
**On Website:**
```javascript
document.getElementById('contact-form').addEventListener('submit', function(e) {
e.preventDefault();
dataLayer.push({
'event': 'form_submit',
'form_name': 'Contact Form',
'form_id': 'contact-form',
'form_destination': '/thank-you',
'user_email_domain': document.getElementById('email').value.split('@')[1]
});
// Then submit form
this.submit();
});
```
### Pattern 5: Video Tracking
**On Website:**
```javascript
// When video starts
dataLayer.push({
'event': 'video_start',
'video_title': 'Product Demo',
'video_duration': 180,
'video_id': 'demo_v1'
});
// When video completes
dataLayer.push({
'event': 'video_complete',
'video_title': 'Product Demo',
'video_percent': 100,
'video_id': 'demo_v1'
});
```
## Advanced Patterns
### Pattern 6: User Authentication
**On Login:**
```javascript
dataLayer.push({
'event': 'login',
'method': 'email',
'user_id': 'user_12345',
'user_tier': 'premium',
'years_customer': 3
});
```
**On Logout:**
```javascript
dataLayer.push({
'event': 'logout',
'user_id': null // Clear user ID
});
```
### Pattern 7: Page Data (For SPAs)
**On Route Change (Single Page Apps):**
```javascript
// React example
useEffect(() => {
dataLayer.push({
'event': 'virtual_page_view',
'page_path': window.location.pathname,
'page_title': document.title,
'page_category': 'products'
});
}, [location]);
```
### Pattern 8: Search Tracking
**On Search:**
```javascript
dataLayer.push({
'event': 'search',
'search_term': searchQuery,
'search_results_count': resultsCount,
'search_category': selectedCategory
});
```
## Data Layer Variable Types in GTM
### Type 1: Simple Data Layer Variable
**Configuration:**
- **Variable Type:** Data Layer Variable
- **Data Layer Variable Name:** `product_id`
- **Data Layer Version:** Version 2
**Usage:** `{{DL - Product ID}}`
### Type 2: Nested Object Access
**For Nested Data:**
```javascript
dataLayer.push({
'ecommerce': {
'value': 99.99,
'items': [...]
}
});
```
**Variable Configuration:**
- **Variable Name:** "DL - Ecommerce Value"
- **Type:** Data Layer Variable
- **Variable Name:** `ecommerce.value`
### Type 3: Array Access
**For Array Elements:**
```javascript
dataLayer.push({
'items': [
{'item_id': 'SKU_123'},
{'item_id': 'SKU_124'}
]
});
```
**Variable for First Item:**
- **Variable Name:** `items.0.item_id` (first array element)
**Better:** Pass entire `items` array to GA4 event parameter
## Timing and Order
### Rule 1: Data Layer BEFORE GTM Container
```html
<script>
window.dataLayer = window.dataLayer || [];
// Can push initial page data here
dataLayer.push({
'page_type': 'product',
'user_tier': 'premium'
});
</script>
<!-- GTM Container Code -->
<script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
```
### Rule 2: Event Push AFTER User Action
```javascript
// CORRECT
button.addEventListener('click', function() {
dataLayer.push({
'event': 'button_click',
'button_name': 'Subscribe'
});
});
// WRONG - Fires on page load before click
dataLayer.push({
'event': 'button_click',
'button_name': 'Subscribe'
});
```
### Rule 3: Clear ecommerce Before Push
**For E-commerce Events:**
```javascript
// Clear previous ecommerce data
dataLayer.push({ ecommerce: null });
// Push new ecommerce data
dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {
'items': [...]
}
});
```
**Why:** Prevents old ecommerce data from persisting
## SPA (Single Page Application) Patterns
### React Example
```javascript
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
useEffect(() => {
// Track virtual page view on route change
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'virtual_page_view',
'page_path': location.pathname,
'page_title': document.title
});
}, [location]);
return <div>...</div>;
}
```
### Vue.js Example
```javascript
// In router/index.js
router.afterEach((to, from) => {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'virtual_page_view',
'page_path': to.path,
'page_title': to.meta.title || document.title
});
});
```
## Debugging Data Layer
### Console Debugging
```javascript
// View entire data layer
console.log(window.dataLayer);
// View last event pushed
console.log(window.dataLayer[window.dataLayer.length - 1]);
// Listen for pushes
var originalPush = window.dataLayer.push;
window.dataLayer.push = function() {
console.log('Data Layer Push:', arguments);
return originalPush.apply(this, arguments);
};
```
### GTM Preview Mode
**Steps:**
1. Click Preview in GTM
2. Interact with website
3. Tag Assistant shows:
- **Data Layer** tab with all pushed events
- Event details and parameters
- Values of variables at time of event
## Common Mistakes
### Mistake 1: Pushing Empty Events
```javascript
// BAD - No data
dataLayer.push({
'event': 'button_click'
});
// GOOD - Include context
dataLayer.push({
'event': 'button_click',
'button_name': 'Subscribe',
'button_location': 'header'
});
```
### Mistake 2: Not Clearing ecommerce
```javascript
// BAD - Old ecommerce data persists
dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {...}
});
// GOOD
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {...}
});
```
### Mistake 3: Using Reserved Keys
**Avoid These Keys:**
- `gtm` (reserved by GTM)
- `google_tag_manager` (reserved)
- `event` (only for trigger names)
### Mistake 4: Wrong Data Types
```javascript
// BAD - String when should be number
dataLayer.push({
'event': 'purchase',
'value': '99.99' // String
});
// GOOD
dataLayer.push({
'event': 'purchase',
'value': 99.99 // Number
});
```
## Best Practices
1. **Initialize Early:** Create `window.dataLayer` before GTM container
2. **Consistent Naming:** Use snake_case for event and parameter names
3. **Clear ecommerce:** Always clear before pushing new ecommerce data
4. **Document Events:** Maintain documentation of all custom events
5. **Test Thoroughly:** Use GTM Preview mode to verify data layer pushes
6. **Avoid PII:** Don't push personal data (emails, names, addresses)
7. **Use Structured Data:** Follow GA4 recommended event structures

View File

@@ -0,0 +1,295 @@
# Complete GTM-GA4 Setup Guide
## Prerequisites
1. **GTM Container Installed** - GTM container code already on website
2. **GA4 Property Created** - GA4 property with Measurement ID available
3. **GTM Editor+ Access** - Required permissions to create/modify tags
## Step-by-Step Setup
### Step 1: Install GTM Container (If Not Already Installed)
**GTM Container Code Location:**
Place in `<head>` section (immediately after `<head>` tag):
```html
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
```
Place noscript fallback in `<body>` (immediately after `<body>` tag):
```html
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
```
### Step 2: Create GA4 Configuration Tag
**In GTM Workspace:**
1. Navigate to **Tags → New**
2. **Tag Name:** "GA4 - Configuration" (or "GA4 - Base Tag")
**Tag Configuration:**
3. Click **Tag Configuration** box
4. Select **Google Tag** (tag type)
5. **Tag ID:** Enter GA4 Measurement ID (format: `G-XXXXXXXXXX`)
- Find in: GA4 Admin → Data Streams → Web Stream → Measurement ID
**Configuration Settings (Optional):**
6. Click **Configuration Settings** (expand if needed)
7. Set optional parameters:
- **send_page_view:** true (default - automatically sends page_view events)
- **allow_google_signals:** true (for Demographics/Remarketing)
- **allow_ad_personalization_signals:** true
**Shared Event Settings (Optional):**
8. Click **Shared Event Settings** to add parameters sent with ALL events:
- Example: `user_tier`, `page_category`, etc.
**Triggering:**
9. Click **Triggering** box
10. Select **Initialization - All Pages**
- This fires BEFORE page_view
- Ensures GA4 loads on every page
**Save:**
11. Click **Save**
**Result:** GA4 Configuration tag created and will fire on all pages
### Step 3: Test GA4 Configuration Tag
**Using GTM Preview Mode:**
1. Click **Preview** button (top-right of GTM)
2. Enter your website URL
3. Click **Connect**
4. Tag Assistant opens in new window
**Verify in Tag Assistant:**
- **Summary** tab shows "Tag Fired: GA4 - Configuration"
- **Tag** appears in "Tags Fired" section
- Event: `gtm.js` (GTM initialization)
- **Initialization** trigger activated
**Verify in GA4 DebugView:**
1. Open GA4 property
2. Go to **Admin → DebugView**
3. See events appearing in real-time:
- `page_view` (automatic from GA4 Configuration tag)
- `session_start`
- `first_visit` (if first time)
### Step 4: Create GA4 Event Tags
**Example: Button Click Event**
**Create Tag:**
1. **Tags → New**
2. **Name:** "GA4 - Button Click - Subscribe"
3. **Tag Configuration → Google Tag**
4. **Tag ID:** Same GA4 Measurement ID (G-XXXXXXXXXX)
5. **Event Name:** `button_click`
**Event Parameters:**
6. Click **Add Parameter**
7. Parameter entries:
- **Parameter Name:** `button_name`**Value:** `{{Button Text}}` (variable)
- **Parameter Name:** `button_location`**Value:** `header`
- **Parameter Name:** `button_id`**Value:** `{{Click ID}}`
**Triggering:**
8. Click **Triggering**
9. Click **"+"** to create new trigger
**Create Trigger:**
10. **Trigger Name:** "Click - Subscribe Button"
11. **Trigger Type:** Click - All Elements
12. **This trigger fires on:** Some Clicks
13. **Filter:**
- **Click ID** → **equals**`subscribe-btn`
14. Click **Save**
**Save Event Tag:**
15. Click **Save**
### Step 5: Create Form Submission Event
**Create Tag:**
1. **Tags → New**
2. **Name:** "GA4 - Form Submit - Contact"
3. **Tag Configuration → Google Tag**
4. **Tag ID:** G-XXXXXXXXXX
5. **Event Name:** `form_submit`
**Event Parameters:**
6. Add Parameters:
- `form_name``{{Form Name}}`
- `form_id``{{Form ID}}`
- `form_destination``/thank-you`
**Create Trigger:**
7. **Triggering → New Trigger**
8. **Name:** "Form - Contact Form Submit"
9. **Type:** Form Submission
10. **Fire on:** Some Forms
11. **Filter:** **Form ID****equals**`contact-form`
12. Save trigger and tag
### Step 6: Implement Custom Event with Data Layer
**On Website (in code):**
```javascript
// When user adds item to cart
document.querySelector('.add-to-cart-btn').addEventListener('click', function() {
dataLayer.push({
'event': 'add_to_cart',
'product_id': 'SKU_123',
'product_name': 'Blue T-Shirt',
'price': 29.99,
'quantity': 1
});
});
```
**In GTM:**
**Create Data Layer Variables:**
1. **Variables → New**
2. **Name:** "DL - Product ID"
3. **Type:** Data Layer Variable
4. **Variable Name:** `product_id`
5. Save
Repeat for `product_name`, `price`, `quantity`
**Create GA4 Event Tag:**
1. **Tags → New**
2. **Name:** "GA4 - Add to Cart"
3. **Tag Type:** Google Tag
4. **Tag ID:** G-XXXXXXXXXX
5. **Event Name:** `add_to_cart`
6. **Parameters:**
- `product_id``{{DL - Product ID}}`
- `product_name``{{DL - Product Name}}`
- `price``{{DL - Price}}`
- `quantity``{{DL - Quantity}}`
**Create Trigger:**
7. **Triggering → New**
8. **Name:** "Custom Event - Add to Cart"
9. **Type:** Custom Event
10. **Event name:** `add_to_cart`
11. Save
### Step 7: Test All Tags with Preview Mode
**Preview Workflow:**
1. Click **Preview** in GTM
2. Connect to website
3. Navigate pages and interact with elements
4. **Tag Assistant** shows:
- Which tags fired
- Which didn't fire (and why)
- Variable values
- Data layer state
**Check Each Event:**
- Click subscribe button → Verify "GA4 - Button Click" fires
- Submit contact form → Verify "GA4 - Form Submit" fires
- Add item to cart → Verify "GA4 - Add to Cart" fires
**Verify in GA4 DebugView:**
- All events appear with correct names
- Parameters populate with expected values
- No duplicate events
### Step 8: Publish GTM Container
**When Ready:**
1. Click **Submit** (top-right)
2. **Version Name:** "GA4 Initial Setup - [Date]"
3. **Version Description:**
```
- Added GA4 Configuration tag
- Added button click tracking
- Added form submission tracking
- Added add_to_cart event via data layer
```
4. Click **Publish**
5. **Result:** Changes live immediately on website
### Step 9: Verify Production
**After Publishing:**
1. Visit website (incognito/private mode)
2. Enable **Google Analytics Debugger** Chrome extension
3. Interact with tracked elements
4. Check **GA4 DebugView** for events
**Wait 24-48 hours:**
- Events appear in standard GA4 reports
- Custom dimensions/metrics populate
## Common Setup Issues
| Issue | Cause | Solution |
|-------|-------|----------|
| **Tags not firing** | Wrong trigger conditions | Check trigger settings in Preview mode |
| **GA4 Configuration not firing** | Wrong trigger selected | Must use "Initialization - All Pages" |
| **Parameters empty** | Variables not created | Create Data Layer Variables first |
| **Duplicate page_views** | Both gtag.js and GTM | Remove gtag.js snippet from website |
| **Events delayed** | Normal processing | Events appear in DebugView immediately, reports in 24-48 hours |
## Best Practices
**Naming Conventions:**
- Tags: "GA4 - [Event Name]"
- Triggers: "[Type] - [Description]"
- Variables: "DL - [Variable Name]" or "GTM - [Built-in Name]"
**Organization:**
- Use folders for related tags/triggers/variables
- Document changes in version descriptions
- Test thoroughly before publishing
- Keep GA4 Configuration tag separate from event tags
**Performance:**
- Use specific triggers (not "All Elements" when possible)
- Minimize data layer pushes
- Batch related events when feasible

View File

@@ -0,0 +1,317 @@
# GTM Preview Mode and Debugging Guide
## Enabling Preview Mode
**Steps:**
1. Open GTM workspace
2. Click **Preview** button (top-right)
3. Enter website URL in popup
4. Click **Connect**
5. New browser tab opens with Tag Assistant
**Result:** Tag Assistant panel shows real-time tag activity
## Tag Assistant Interface
### Summary Tab
**Shows:**
- Tags Fired count
- Tags Not Fired count
- Data Layer Messages
- Event timeline
### Tags Tab
**Categories:**
- **Tags Fired:** Successfully triggered tags
- **Tags Not Fired:** Tags that didn't trigger
- **Tag Firing Failed:** Tags with errors
**For Each Tag:**
- Tag name
- Trigger that fired it
- Variables used
- Parameters sent
### Variables Tab
**Shows All Variables:**
- Name
- Current value
- Type
- Last updated
### Data Layer Tab
**Shows:**
- All dataLayer pushes
- Event details
- Parameters
- Timestamp
### Errors Tab
**Shows:**
- JavaScript errors
- Tag firing errors
- Configuration issues
## Debugging Workflow
### Step 1: Verify GA4 Configuration Tag
**In Tag Assistant:**
1. Look for **"GA4 - Configuration"** in **Tags Fired**
2. Check it fired on **Initialization - All Pages** trigger
3. Verify Tag ID is correct (G-XXXXXXXXXX)
**Expected:** Fires on every page load
### Step 2: Test Event Tags
**Workflow:**
1. Trigger expected action (click button, submit form)
2. Check **Tags Fired** for corresponding GA4 event tag
3. Expand tag to see:
- **Event Name:** Correct event name
- **Event Parameters:** Populated with expected values
- **Trigger:** Correct trigger fired
**Example: Button Click**
- Click "Subscribe" button
- Verify "GA4 - Button Click - Subscribe" in Tags Fired
- Check Event Parameters:
- `button_name`: "Subscribe Now"
- `button_location`: "header"
### Step 3: Verify Variables
**In Variables Tab:**
1. Locate variable (e.g., "DL - Product ID")
2. Check **Value** column
3. Verify value matches expected data
**Common Variables to Check:**
- Data Layer Variables
- Click Variables (after clicking element)
- Form Variables (after form interaction)
- Page Variables (on page load)
### Step 4: Check Data Layer
**In Data Layer Tab:**
1. See all `dataLayer.push()` calls
2. Expand each message
3. Verify structure and values
**Example:**
```
Message: {event: "add_to_cart", product_id: "SKU_123", ...}
Event: add_to_cart
Variables:
- product_id: "SKU_123"
- product_name: "Blue T-Shirt"
- price: 29.99
```
### Step 5: Verify in GA4 DebugView
**After Tags Fire in GTM:**
1. Open GA4 property
2. Go to **Admin → DebugView**
3. Events appear in real-time
4. Click event to see parameters
**Verify:**
- Event name matches GTM event name
- Parameters match GTM event parameters
- Values are correct types (strings, numbers)
## Common Debugging Scenarios
### Scenario 1: Tag Not Firing
**Symptoms:**
- Tag appears in **Tags Not Fired**
- Expected action performed but tag doesn't fire
**Troubleshooting:**
1. **Check Trigger Conditions:**
- Expand tag in **Tags Not Fired**
- See "Why didn't this tag fire?"
- Review trigger conditions
2. **Verify Trigger Variables:**
- Check variables used in trigger
- Ensure they have expected values
3. **Check Trigger Type:**
- Click trigger: Did you click the right element?
- Form trigger: Did form actually submit?
- Custom Event: Was event pushed to dataLayer?
4. **Check Exceptions:**
- Tag may have exception preventing firing
**Example Fix:**
- **Problem:** Click trigger for button ID "subscribe-btn" not firing
- **Check:** Click ID variable value
- **Find:** Actual button ID is "subscribe-button"
- **Fix:** Update trigger condition
### Scenario 2: Wrong Variable Value
**Symptoms:**
- Tag fires but parameter value is wrong/empty
- Variable shows `undefined` or wrong data
**Troubleshooting:**
1. **Check Variable Configuration:**
- Data Layer Variable: Verify key name (case-sensitive)
- JavaScript Variable: Check global variable exists
- Click Variable: Ensure element has attribute
2. **Check Data Layer:**
- Go to Data Layer tab
- Find relevant dataLayer push
- Verify key exists and has value
3. **Check Timing:**
- Variable may not be set when tag fires
- Ensure data layer push happens BEFORE tag fires
**Example Fix:**
- **Problem:** `product_id` variable empty
- **Check:** Data Layer tab
- **Find:** Key is `productId` (camelCase), not `product_id`
- **Fix:** Update variable name to `productId`
### Scenario 3: Duplicate Events
**Symptoms:**
- Same event fires multiple times
- Duplicate events in GA4
**Troubleshooting:**
1. **Check for Multiple Triggers:**
- Same event tag may have multiple triggers
- Review tag's triggering section
2. **Check for Multiple Tags:**
- Multiple tags for same event
- Search for duplicate tag names
3. **Check for gtag.js + GTM:**
- Website may have both gtag.js snippet AND GTM
- Remove gtag.js if using GTM
**Example Fix:**
- **Problem:** `page_view` firing twice
- **Find:** Both gtag.js snippet in <head> and GTM GA4 Configuration tag
- **Fix:** Remove gtag.js snippet
### Scenario 4: Missing Event Parameters
**Symptoms:**
- Event fires but some parameters missing
- GA4 DebugView shows event without expected parameters
**Troubleshooting:**
1. **Check Tag Configuration:**
- Expand tag in Preview
- Verify all parameters added to tag
2. **Check Variable Values:**
- Variables Tab: Check parameter variables have values
- Empty variables won't send parameters
3. **Check Data Layer:**
- Ensure data layer includes all expected keys
- Verify spelling and case
**Example Fix:**
- **Problem:** `item_category` parameter missing from `add_to_cart`
- **Check:** Variables Tab
- **Find:** `DL - Item Category` has value `undefined`
- **Root Cause:** dataLayer push missing `item_category` key
- **Fix:** Update dataLayer push to include `item_category`
## Advanced Debugging
### Debugging Data Layer
**View in Console:**
```javascript
// View entire data layer
window.dataLayer
// View last message
window.dataLayer[window.dataLayer.length - 1]
// Monitor pushes
var _push = window.dataLayer.push;
window.dataLayer.push = function() {
console.log('dataLayer push:', arguments);
return _push.apply(this, arguments);
};
```
### Debugging Triggers
**Test Trigger Manually:**
1. Preview mode active
2. Open Console
3. Manually push event:
```javascript
dataLayer.push({'event': 'test_event'});
```
4. Check if trigger fires
### Debugging Variables
**Check Variable in Console:**
```javascript
// For built-in variables
google_tag_manager['GTM-XXXXXXX'].dataLayer.get('variableName')
// For data layer
window.dataLayer.find(item => item.product_id)
```
## Testing Checklist
**Before Publishing:**
- [ ] GA4 Configuration tag fires on all pages
- [ ] All event tags fire when expected
- [ ] No tags in "Tags Not Fired" section
- [ ] Variables populate with correct values
- [ ] Event parameters sent to GA4
- [ ] No duplicate events firing
- [ ] Data Layer pushes correctly formatted
- [ ] Events appear in GA4 DebugView
- [ ] Parameters match expected values in DebugView
- [ ] No JavaScript errors in Errors tab
## Best Practices
**During Development:**
1. Test each tag immediately after creating
2. Use Preview mode for every change
3. Verify in both GTM and GA4 DebugView
4. Document expected behavior
5. Test on multiple pages/scenarios
**Before Publishing:**
1. Complete testing checklist
2. Test with team members
3. Document all tags/triggers/variables
4. Create version description
5. Schedule publication during low-traffic period
**After Publishing:**
1. Verify tags still working in production
2. Monitor GA4 DebugView for 30 minutes
3. Check standard GA4 reports next day
4. Monitor for anomalies

View File

@@ -0,0 +1,429 @@
# GTM Tags, Triggers, and Variables Reference for GA4
## Tag Types for GA4
### Google Tag (GA4 Configuration Tag)
**Purpose:** Initialize GA4 tracking on pages
**Configuration:**
- **Tag ID:** GA4 Measurement ID (G-XXXXXXXXXX)
- **Trigger:** Initialization - All Pages
- **send_page_view:** true (automatic page_view events)
**When to Use:** One per GA4 property, fires on all pages
### Google Tag (GA4 Event Tag)
**Purpose:** Track specific events
**Configuration:**
- **Tag ID:** Same GA4 Measurement ID
- **Event Name:** Specific event (e.g., `button_click`, `purchase`)
- **Event Parameters:** Additional data
**When to Use:** Each specific event you want to track
## Trigger Types
### Page View Triggers
**All Pages**
- Fires on: Every page load
- Use for: GA4 Configuration tag
**Some Pages**
- Fires on: Pages matching conditions
- Conditions: Page Path, Page URL, Page Hostname
- Example: Page Path contains `/checkout`
**DOM Ready**
- Fires when: DOM fully loaded
- Use for: Tags requiring DOM elements
**Window Loaded**
- Fires when: Page fully loaded (images, CSS, JS)
- Use for: Tags after full page load
### Click Triggers
**All Elements**
- Fires on: Any click
- Filter by: Click ID, Class, URL, Text
- Example: Click ID equals `subscribe-btn`
**Just Links**
- Fires on: `<a>` tag clicks only
- Filter by: Click URL contains, starts with, equals
- Example: Outbound link tracking
### Form Triggers
**Form Submission**
- Fires when: Form submitted
- Filter by: Form ID, Class, URL, Text
- Example: Form ID equals `contact-form`
**Form Start** (Built-in Variable)
- Fires when: User interacts with form first time
- Use for: Form abandonment tracking
### Custom Event Triggers
**Custom Event**
- Fires when: `dataLayer.push({event: 'event_name'})`
- Event name: Exact match to data layer event
- Example: Event name = `add_to_cart`
### Scroll Depth Trigger
**Scroll Depth**
- Fires on: Vertical scroll percentages
- Thresholds: 25%, 50%, 75%, 90%
- Use for: Content engagement tracking
### Element Visibility Trigger
**Element Visibility**
- Fires when: Element visible on screen
- Selection Method: ID, CSS Selector
- Use for: Scroll-based element tracking
### Timer Trigger
**Timer**
- Fires on: Time intervals
- Interval: Milliseconds
- Limit: Optional max fires
- Use for: Engagement time tracking
## Variable Types
### Built-in Variables (Enable in Variables Section)
**Page Variables:**
- Page URL (full URL)
- Page Hostname (domain only)
- Page Path (path only, no domain)
- Referrer (previous page URL)
**Click Variables:**
- Click Element (entire element)
- Click Classes (CSS classes)
- Click ID (element ID)
- Click Target (link target)
- Click Text (visible text)
- Click URL (link href)
**Form Variables:**
- Form Element (entire form)
- Form Classes (CSS classes)
- Form ID (form ID attribute)
- Form Target (form target)
- Form Text (visible text in form)
- Form URL (form action URL)
**Utilities:**
- Random Number
- Debug Mode (true in Preview)
- Container ID (GTM-XXXXXXX)
- Container Version
### Custom Variables
**Data Layer Variable**
- Type: Data Layer Variable
- Variable Name: Key from `dataLayer` (e.g., `product_id`)
- Use: Access data layer values
**JavaScript Variable**
- Type: JavaScript Variable
- Global Variable Name: JavaScript variable name
- Example: `window.location.hostname`
**1st Party Cookie**
- Type: 1st Party Cookie
- Cookie Name: Name of cookie
- Use: Read cookie values
**Custom JavaScript**
- Type: Custom JavaScript
- Returns: Value from custom function
**Example:**
```javascript
function() {
return document.querySelector('.product-price').textContent;
}
```
**Lookup Table**
- Type: Lookup Table
- Input Variable: Variable to map
- Mapping: Input value → Output value
**Example:**
- Input: `{{Page Type}}`
- `product``product_page`
- `category``category_page`
**RegEx Table**
- Type: RegEx Table
- Pattern matching with regex
- Use: Complex URL/path mapping
## Common Tag Configurations
### 1. GA4 Configuration Tag
```
Tag Type: Google Tag
Tag ID: G-XXXXXXXXXX
Trigger: Initialization - All Pages
Configuration Settings:
- send_page_view: true
- allow_google_signals: true
```
### 2. Button Click Event Tag
```
Tag Type: Google Tag
Tag ID: G-XXXXXXXXXX
Event Name: button_click
Event Parameters:
- button_name: {{Button Text}}
- button_location: header
Trigger: Click - Subscribe Button
```
### 3. Form Submission Tag
```
Tag Type: Google Tag
Tag ID: G-XXXXXXXXXX
Event Name: form_submit
Event Parameters:
- form_name: {{Form Name}}
- form_id: {{Form ID}}
- form_destination: /thank-you
Trigger: Form - Contact Form Submit
```
### 4. Add to Cart Tag (Data Layer)
```
Tag Type: Google Tag
Tag ID: G-XXXXXXXXXX
Event Name: add_to_cart
Event Parameters:
- items: {{DL - Ecommerce Items}}
- value: {{DL - Ecommerce Value}}
- currency: {{DL - Ecommerce Currency}}
Trigger: Custom Event - add_to_cart
```
### 5. Purchase Tag (Data Layer)
```
Tag Type: Google Tag
Tag ID: G-XXXXXXXXXX
Event Name: purchase
Event Parameters:
- transaction_id: {{DL - Transaction ID}}
- value: {{DL - Ecommerce Value}}
- currency: {{DL - Ecommerce Currency}}
- tax: {{DL - Tax}}
- shipping: {{DL - Shipping}}
- items: {{DL - Ecommerce Items}}
Trigger: Custom Event - purchase
```
## Common Trigger Configurations
### 1. All Pages Trigger
```
Trigger Type: Page View - All Pages
Fires on: All page views
Use: GA4 Configuration tag
```
### 2. Specific Page Trigger
```
Trigger Type: Page View - Some Pages
Fires on: Some Pages
Condition: Page Path contains /checkout
Use: Checkout page tracking
```
### 3. Click - Specific Button
```
Trigger Type: Click - All Elements
Fires on: Some Clicks
Condition: Click ID equals subscribe-btn
Use: Button click events
```
### 4. Click - Outbound Links
```
Trigger Type: Click - Just Links
Fires on: Some Link Clicks
Condition: Click URL does not contain {{Page Hostname}}
Use: External link tracking
```
### 5. Form - Specific Form
```
Trigger Type: Form Submission
Fires on: Some Forms
Condition: Form ID equals contact-form
Use: Form submission tracking
```
### 6. Custom Event - Data Layer
```
Trigger Type: Custom Event
Event name: add_to_cart
Use: Data layer event tracking
```
### 7. Scroll Depth
```
Trigger Type: Scroll Depth
Vertical Scroll Depths: 25, 50, 75, 90
Fires on: All Pages
Use: Content engagement
```
### 8. Element Visibility
```
Trigger Type: Element Visibility
Selection Method: ID
Element Selector: video-player
Fires on: Page View
Minimum Percent Visible: 50%
Use: Video player visibility
```
## Advanced Configurations
### Trigger Groups (AND Logic)
**Some Clicks with Multiple Conditions:**
```
Fires on: Some Clicks
Conditions (ALL must match):
- Click Classes contains cta-button
- Click URL does not contain #
- Page Path equals /pricing
```
### Trigger Exceptions
**Fire Except on Certain Pages:**
```
Tag: GA4 - Page View Enhanced
Trigger: All Pages
Exception: Admin Pages (Page Path contains /admin)
```
### Variable Fallbacks
**Using Lookup Table with Default:**
```
Input: {{Page Type}}
Table:
- product → product_page
- category → category_page
Default Value: other_page
```
## Naming Conventions
**Tags:**
- Format: `[Platform] - [Event/Type] - [Description]`
- Examples:
- `GA4 - Configuration`
- `GA4 - Button Click - Subscribe`
- `GA4 - Purchase`
**Triggers:**
- Format: `[Type] - [Description]`
- Examples:
- `All Pages`
- `Click - Subscribe Button`
- `Form - Contact Form Submit`
- `Custom Event - add_to_cart`
**Variables:**
- Format: `[Source] - [Variable Name]`
- Examples:
- `DL - Product ID` (Data Layer)
- `GTM - Page Path` (Built-in)
- `JS - User Tier` (JavaScript)
- `Cookie - Session ID` (1st Party Cookie)
## Testing Configurations
### Using Preview Mode
**Steps:**
1. Set up tag/trigger/variable
2. Click Preview
3. Connect to site
4. Trigger expected behavior
5. Verify in Tag Assistant:
- Tag fires
- Variables populate correctly
- Parameters sent to GA4
### Common Test Scenarios
**Test 1: Click Trigger**
- Click element
- Verify tag fires
- Check Click Variables populate
**Test 2: Form Trigger**
- Fill form
- Submit
- Verify tag fires after submission
- Check Form Variables
**Test 3: Data Layer Event**
- Trigger data layer push
- Verify Custom Event trigger fires
- Check Data Layer Variables
**Test 4: Page View**
- Navigate to specific page
- Verify trigger conditions met
- Check Page Variables
## Troubleshooting
**Tag Not Firing:**
- Check trigger conditions in Preview
- Verify variables have values
- Check trigger exceptions
**Wrong Variable Value:**
- Check variable type configuration
- Verify data layer key name (case-sensitive)
- Check variable persistence settings
**Duplicate Firing:**
- Check for multiple matching triggers
- Review trigger conditions for overlap
- Check tag firing priorities