| name | gtm-javascript |
| description | Generate ES5-compliant JavaScript for Google Tag Manager Custom HTML tags. Use when writing GTM tags, dataLayer code, or analytics implementations. |
GTM JavaScript Coding Standards
This skill ensures all JavaScript code generated for Google Tag Manager (GTM) Custom HTML tags is ES5-compliant and follows current best practices (2024-2025).
Critical Constraint: ES5 Only
GTM's JavaScript compiler operates in ES5 (ECMAScript 5) mode by default. ES6+ syntax causes compilation errors and prevents tag publishing.
Prohibited ES6+ Features
NEVER use these in GTM Custom HTML tags:
| Feature | ES6+ (Prohibited) | ES5 (Required) |
|---|---|---|
| Variables | const, let |
var |
| Functions | () => {} |
function() {} |
| Strings | `${var}` |
'str' + var |
| Destructuring | {a, b} = obj |
var a = obj.a |
| Spread | [...arr] |
arr.concat() |
| Default params | fn(x = 1) |
x = x || 1 |
| for-of | for (x of arr) |
for (var i...) |
| Classes | class Foo {} |
function Foo(){} |
| Block functions | if(x){function f(){}} |
if(x){var f=function(){}} |
2024-2025 Updates
Breaking Changes
- IE11 Support Ended (July 15, 2024): No longer tested or fixed
- Consent Mode v2 Required (March 2024): New parameters
ad_user_dataandad_personalization - Google Ads Auto-Tag (April 10, 2025): Containers with Google Ads tags auto-load Google tag first
New Features
- Tag Diagnostics tool for issue detection
gtagSetAPI for configuration settingsreadAnalyticsStoragesandbox API for custom templates- Server-side GTM can load scripts via 1st-party domain
Code Patterns
IIFE Pattern (Recommended)
(function() {
'use strict';
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'my_event',
my_parameter: 'value'
});
})();
Error Handling
(function() {
'use strict';
try {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({event: 'tracked_event'});
} catch (e) {
// Silent fail - do not break page
}
})();
Array Iteration (ES5)
function forEach(arr, callback) {
for (var i = 0; i < arr.length; i++) {
callback(arr[i], i);
}
}
Consent Mode v2
When implementing consent, use these parameters:
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
// Default state (before consent)
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied'
});
// After user grants consent
gtag('consent', 'update', {
ad_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted',
analytics_storage: 'granted'
});
GA4 Ecommerce Events
Use the standard event names and items array structure:
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'T12345',
value: 99.99,
currency: 'USD',
items: [{
item_id: 'SKU123',
item_name: 'Product Name',
price: 99.99,
quantity: 1
}]
}
});
Validation Checklist
Before publishing any GTM tag:
- No
const/let- usevaronly - No arrow functions - use
function()syntax - No template literals - use string concatenation
- No destructuring - access properties individually
- No for-of loops - use traditional for loops
- No block-scoped function declarations
- Test in GTM Preview Mode
- Verify in GA4 DebugView (if applicable)
- Check browser console for errors
Resources
When to Use Custom Templates Instead
Consider using Custom Templates (not Custom HTML) when:
- Building reusable tag logic
- Need sandboxed security
- Want permission-based access control
- Sharing with organization
Custom Templates support some ES6 features and provide better security through the sandboxed JavaScript environment.