Skip to content

Google Tag Manager Implementation Reference

Google Tag Manager Implementation Reference

Section titled “Google Tag Manager Implementation Reference”

Detailed guide for implementing tracking via Google Tag Manager.

  • Container Structure (tags, triggers, variables)
  • Naming Conventions
  • Data Layer Patterns
  • Common Tag Configurations (GA4 configuration tag, GA4 event tag, Facebook pixel)
  • Preview and Debug
  • Workspaces and Versioning
  • Consent Management
  • Advanced Patterns (tag sequencing, exception handling, custom JavaScript variables)

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 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 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

[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

// Initialize (in <head> before GTM)
window.dataLayer = window.dataLayer || [];
// Push event
dataLayer.push({
'event': 'event_name',
'property1': 'value1',
'property2': 'value2'
});
// Set on page load (before GTM container)
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'pageType': 'product',
'contentGroup': 'products',
'user': {
'loggedIn': true,
'userId': '12345',
'userType': 'premium'
}
});
document.querySelector('#contact-form').addEventListener('submit', function() {
dataLayer.push({
'event': 'form_submitted',
'formName': 'contact',
'formLocation': 'footer'
});
});
document.querySelector('.cta-button').addEventListener('click', function() {
dataLayer.push({
'event': 'cta_clicked',
'ctaText': this.innerText,
'ctaLocation': 'hero'
});
});
// 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
}]
}
});

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

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

Tag Type: Custom HTML

<script>
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
</script>

Trigger: All Pages

Tag Type: Custom HTML

<script>
fbq('track', 'Lead', {
content_name: '{{DL - form_name}}'
});
</script>

Trigger: Custom Event - form_submitted


  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

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

Use workspaces for team collaboration:

  • Default workspace for production
  • Separate workspaces for large changes
  • Merge when ready

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

// 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'
});
}
  1. Enable Consent Overview in Admin
  2. Configure consent for each tag
  3. Tags respect consent state automatically

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

Trigger exceptions - Prevent tag from firing:

  • Exclude certain pages
  • Exclude internal traffic
  • Exclude during testing
// 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;
}