# Google Tag Manager Implementation Reference Detailed guide for implementing tracking via Google Tag Manager. ## Container Structure ### Tags Tags are code snippets that execute when triggered. **Common tag types:** - GA4 Configuration (base setup) - GA4 Event (custom events) - Google Ads Conversion - Facebook Pixel - LinkedIn Insight Tag - Custom HTML (for other pixels) ### Triggers Triggers define when tags fire. **Built-in triggers:** - Page View: All Pages, DOM Ready, Window Loaded - Click: All Elements, Just Links - Form Submission - Scroll Depth - Timer - Element Visibility **Custom triggers:** - Custom Event (from dataLayer) - Trigger Groups (multiple conditions) ### Variables Variables capture dynamic values. **Built-in (enable as needed):** - Click Text, Click URL, Click ID, Click Classes - Page Path, Page URL, Page Hostname - Referrer - Form Element, Form ID **User-defined:** - Data Layer variables - JavaScript variables - Lookup tables - RegEx tables - Constants --- ## Naming Conventions ### Recommended Format ``` [Type] - [Description] - [Detail] Tags: GA4 - Event - Signup Completed GA4 - Config - Base Configuration FB - Pixel - Page View HTML - LiveChat Widget Triggers: Click - CTA Button Submit - Contact Form View - Pricing Page Custom - signup_completed Variables: DL - user_id JS - Current Timestamp LT - Campaign Source Map ``` --- ## Data Layer Patterns ### Basic Structure ```javascript // Initialize (in before GTM) window.dataLayer = window.dataLayer || []; // Push event dataLayer.push({ 'event': 'event_name', 'property1': 'value1', 'property2': 'value2' }); ``` ### Page Load Data ```javascript // Set on page load (before GTM container) window.dataLayer = window.dataLayer || []; dataLayer.push({ 'pageType': 'product', 'contentGroup': 'products', 'user': { 'loggedIn': true, 'userId': '12345', 'userType': 'premium' } }); ``` ### Form Submission ```javascript document.querySelector('#contact-form').addEventListener('submit', function() { dataLayer.push({ 'event': 'form_submitted', 'formName': 'contact', 'formLocation': 'footer' }); }); ``` ### Button Click ```javascript document.querySelector('.cta-button').addEventListener('click', function() { dataLayer.push({ 'event': 'cta_clicked', 'ctaText': this.innerText, 'ctaLocation': 'hero' }); }); ``` ### E-commerce Events ```javascript // Product view dataLayer.push({ ecommerce: null }); // Clear previous dataLayer.push({ 'event': 'view_item', 'ecommerce': { 'items': [{ 'item_id': 'SKU123', 'item_name': 'Product Name', 'price': 99.99, 'item_category': 'Category', 'quantity': 1 }] } }); // Add to cart dataLayer.push({ ecommerce: null }); dataLayer.push({ 'event': 'add_to_cart', 'ecommerce': { 'items': [{ 'item_id': 'SKU123', 'item_name': 'Product Name', 'price': 99.99, 'quantity': 1 }] } }); // Purchase dataLayer.push({ ecommerce: null }); dataLayer.push({ 'event': 'purchase', 'ecommerce': { 'transaction_id': 'T12345', 'value': 99.99, 'currency': 'USD', 'tax': 5.00, 'shipping': 10.00, 'items': [{ 'item_id': 'SKU123', 'item_name': 'Product Name', 'price': 99.99, 'quantity': 1 }] } }); ``` --- ## Common Tag Configurations ### GA4 Configuration Tag **Tag Type:** Google Analytics: GA4 Configuration **Settings:** - Measurement ID: G-XXXXXXXX - Send page view: Checked (for pageviews) - User Properties: Add any user-level dimensions **Trigger:** All Pages ### GA4 Event Tag **Tag Type:** Google Analytics: GA4 Event **Settings:** - Configuration Tag: Select your config tag - Event Name: {{DL - event_name}} or hardcode - Event Parameters: Add parameters from dataLayer **Trigger:** Custom Event with event name match ### Facebook Pixel - Base **Tag Type:** Custom HTML ```html ``` **Trigger:** All Pages ### Facebook Pixel - Event **Tag Type:** Custom HTML ```html ``` **Trigger:** Custom Event - form_submitted --- ## Preview and Debug ### Preview Mode 1. Click "Preview" in GTM 2. Enter site URL 3. GTM debug panel opens at bottom **What to check:** - Tags fired on this event - Tags not fired (and why) - Variables and their values - Data layer contents ### Debug Tips **Tag not firing:** - Check trigger conditions - Verify data layer push - Check tag sequencing **Wrong variable value:** - Check data layer structure - Verify variable path (nested objects) - Check timing (data may not exist yet) **Multiple firings:** - Check trigger uniqueness - Look for duplicate tags - Check tag firing options --- ## Workspaces and Versioning ### Workspaces Use workspaces for team collaboration: - Default workspace for production - Separate workspaces for large changes - Merge when ready ### Version Management **Best practices:** - Name every version descriptively - Add notes explaining changes - Review changes before publish - Keep production version noted **Version notes example:** ``` v15: Added purchase conversion tracking - New tag: GA4 - Event - Purchase - New trigger: Custom Event - purchase - New variables: DL - transaction_id, DL - value - Tested: Chrome, Safari, Mobile ``` --- ## Consent Management ### Consent Mode Integration ```javascript // Default state (before consent) gtag('consent', 'default', { 'analytics_storage': 'denied', 'ad_storage': 'denied' }); // Update on consent function grantConsent() { gtag('consent', 'update', { 'analytics_storage': 'granted', 'ad_storage': 'granted' }); } ``` ### GTM Consent Overview 1. Enable Consent Overview in Admin 2. Configure consent for each tag 3. Tags respect consent state automatically --- ## Advanced Patterns ### Tag Sequencing **Setup tags to fire in order:** Tag Configuration > Advanced Settings > Tag Sequencing **Use cases:** - Config tag before event tags - Pixel initialization before tracking - Cleanup after conversion ### Exception Handling **Trigger exceptions** - Prevent tag from firing: - Exclude certain pages - Exclude internal traffic - Exclude during testing ### Custom JavaScript Variables ```javascript // Get URL parameter function() { var params = new URLSearchParams(window.location.search); return params.get('campaign') || '(not set)'; } // Get cookie value function() { var match = document.cookie.match('(^|;) ?user_id=([^;]*)(;|$)'); return match ? match[2] : null; } // Get data from page function() { var el = document.querySelector('.product-price'); return el ? parseFloat(el.textContent.replace('$', '')) : 0; } ```