GTM Best Practices
Sources:
Last Updated: 2025-01-09
Overview
This guide covers best practices for Google Tag Manager including naming conventions, performance optimisation, security, privacy compliance, and deployment strategies. Following these practices ensures maintainable, secure, and efficient GTM implementations.
Technical Constraints
JavaScript (ES5 Requirement)
Critical: GTM Custom JavaScript Variables and Custom HTML Tags require ECMAScript 5 (ES5) syntax.
ES6 Features NOT Supported
// WILL FAIL - ES6 syntax
const myVar = 'value';
let count = 0;
const arrow = () => console.log('test');
const template = `Hello ${name}`;
// CORRECT - ES5 syntax
var myVar = 'value';
var count = 0;
var regularFunc = function() { console.log('test'); };
var concatenated = 'Hello ' + name;
Custom Templates Exception
Custom Templates (sandboxed JavaScript) support some ES6 features:
constandletdeclarations- Template literals
- Limited modern JavaScript features
Workarounds
Option 1: Transpilation (Recommended)
Use BabelJS to transpile ES6+ to ES5 before pasting into GTM.
Option 2: text/gtmscript Tag
Bypass GTM's syntax checking (use with caution):
<script type="text/gtmscript">
// Modern JavaScript here - no syntax validation in GTM UI
const myModernCode = () => {
// ...
};
</script>
Caveats:
- No syntax highlighting in GTM interface
- No error checking until runtime
- Harder to debug
Regular Expressions (RE2 Format)
Critical: GTM uses RE2 (GoLang regex), NOT standard JavaScript/PCRE regex.
Not Supported in RE2
- Backreferences:
\1,\2 - Lookahead:
(?=...),(?!...) - Lookbehind:
(?<=...),(?<!...) - Conditional expressions
- 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
# Match product pages
^/products/[^/]+$
# Category with ID
^/category/\d+
# Case-insensitive matching
(?i)^/checkout
# Multiple domains
^https://(www\.)?example\.(com|net)
Naming Conventions
Tags
Format: [Platform] - [Type] - [Description]
Examples:
GA4 - Config - Main PropertyGA4 - Event - Form SubmitGA4 - Event - Purchase CompleteGoogle Ads - Conversion - Form SubmitGoogle Ads - Remarketing - All PagesFB - Pixel - Page ViewLinkedIn - Insight - All PagesCustom - Hotjar - Initialisation
Triggers
Format: [Event Type] - [Description]
Examples:
Pageview - All PagesPageview - Product PagesClick - CTA ButtonsClick - Outbound LinksForm - Contact FormCustom Event - PurchaseScroll - 50% Blog PostsTimer - 30 SecondsHistory Change - All
Variables
Format: [Type] - [Description]
Prefixes:
DL- Data Layer VariableCJS- Custom JavaScriptJS- JavaScript VariableConst- ConstantLookup- Lookup TableRegex- Regex TableURL- URL VariableCookie- First Party CookieDOM- DOM Element
Examples:
DL - User IDDL - Transaction TotalDL - Product NameCJS - Page CategoryCJS - Formatted PriceConst - GA4 Measurement IDConst - FB Pixel IDURL - UTM SourceCookie - Session IDLookup - Page Type
Folders
Organise by platform or purpose:
Analytics/
GA4 Tags
GA4 Triggers
GA4 Variables
Advertising/
Google Ads
Facebook
LinkedIn
Utilities/
Error Tracking
Performance Monitoring
Testing/
Development Tags
Container Organisation
Workspace Management
Development Workflow:
- Create workspace for each feature/change
- Name workspace descriptively:
Add GA4 Ecommerce Tracking - Work in isolation
- Test thoroughly in Preview mode
- Submit for review
- Merge and publish
Best Practices:
- One feature per workspace
- Regular cleanup of abandoned workspaces
- Clear workspace descriptions
- Resolve conflicts promptly
Version Control
Version Naming:
v[Major].[Minor] - [Description]
Examples:
v1.0 - Initial GTM Setupv1.1 - Add GA4 Ecommercev2.0 - Major Restructurev2.1 - Fix Checkout Tracking
Version Notes Template:
Changes:
- Added GA4 purchase event tracking
- Updated data layer structure for checkout
- Fixed duplicate page view issue
Testing:
- Verified in dev environment
- Tested all checkout flows
- Confirmed data in GA4 DebugView
Tags Added:
- GA4 - Event - Purchase Complete
Tags Modified:
- GA4 - Event - Add to Cart (updated parameters)
User Permissions
Permission Levels:
- No Access: External users
- Read: Stakeholders, analysts (view only)
- Edit: Developers, marketers
- Approve: Senior developers, managers
- Publish: Select trusted users only
Performance Optimisation
Tag Load Order
Use tag firing priority (higher numbers fire first):
100 - Critical tags (error tracking, consent)
50 - Analytics tags (GA4, Adobe)
25 - Marketing tags (ads pixels)
10 - Third-party tags
0 - Default
Minimise Custom HTML
Prefer (in order):
- Built-in tags (GA4, Google Ads)
- Community Gallery templates
- Custom templates
- Custom HTML (last resort)
Why:
- Built-in tags are optimised
- Less maintenance
- Better performance
- Reduced security risk
Tag Timeout
Configure timeout in Admin > Container Settings > Tag Settings:
- Default: 2000ms (2 seconds)
- Recommended: 3000-5000ms for complex tags
Prevents:
- Tags blocking page indefinitely
- Poor user experience
- False abandonment metrics
Container Size
Keep container lean:
- Remove unused tags, triggers, variables
- Consolidate duplicate functionality
- Audit quarterly
- Monitor container size
Security Best Practices
Custom HTML Security
Security Checklist:
- No dangerous functions with user input
- No document.write() with external sources
- Validate all external script sources
- Review third-party tag code
- Use CSP (Content Security Policy) headers
Data Layer Security
Never Push PII:
// NEVER DO THIS
dataLayer.push({
'email': 'user@example.com',
'phone': '+1234567890'
});
// HASH OR PSEUDONYMISE
dataLayer.push({
'userIdHash': sha256('user@example.com'),
'hasPhone': true
});
Template Permissions
Review custom template permissions:
- Access to APIs
- Access to global variables
- Access to local storage
- Network requests
Grant minimum necessary permissions.
Quality Assurance
Testing Checklist
Before Publishing:
- Preview mode testing completed
- All triggers fire correctly
- Data layer variables populate
- Tags send expected data
- No console errors
- Cross-browser testing
- Mobile testing
- Edge case scenarios tested
Debug Workflow
- Enable Preview Mode
- Navigate to test page
- Verify in Debug Panel:
- Tags Fired
- Tags Not Fired
- Data Layer
- Variables
- Check receiving platform (GA4, Google Ads, etc.)
- Test edge cases
Deployment Best Practices
Publishing Workflow
- Development: Test in development workspace
- Staging: Test in staging environment
- Preview: Final check in preview mode
- Publish: Publish to live container
- Monitor: Watch for errors/issues
Emergency Rollback
Quick Rollback:
Versions > Previous Version > Actions > Publish
Keep:
- Last 3 working versions readily accessible
- Emergency contact list
- Rollback documentation
Production Deployment Checklist
- Workspace approved by team lead
- All tests passing
- Change documented in version notes
- Stakeholders notified
- Monitoring in place
- Rollback plan ready
Maintenance
Regular Audits
Quarterly Review:
- Remove unused tags/triggers/variables
- Update deprecated features
- Review tag performance
- Check for duplicate tracking
- Verify naming consistency
Performance Monitoring
Monitor:
- Page load time impact
- Tag load time
- Failed tags
- Timeout events
- Error rates
Tools:
- Google Tag Assistant
- Chrome DevTools
- GTM Debug Panel
- GA4 DebugView
Version Cleanup
Retention Policy:
- Keep last 10-15 versions
- Archive old versions
- Document reason for major changes
- Maintain change history
Documentation
External Documentation
Maintain:
GTM Implementation Guide
- Container architecture
- Tag inventory
- Trigger mapping
- Variable dictionary
- Data layer specification
Change Log
- Date of change
- Description
- Who made the change
- Reason for change
Troubleshooting Guide
- Common issues
- Solutions
- Contact information