Required Fields
Universal Data Layer Variables
These variables should be available on every page:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
'pageType': 'home', // home, product, category, cart, checkout, confirmation
'siteEnvironment': 'production', // development, staging, production
'consentState': {
'analytics': true,
'advertising': true,
'personalization': true
},
'user': {
'userId': null, // Populate for logged-in users
'customerType': 'guest', // guest, new, returning
'loginState': 'logged_out' // logged_in, logged_out
}
});
Product Page Data Layer
Required on product detail pages:
dataLayer.push({
'pageType': 'product',
'product': {
'id': 'ASIN-B08N5WRWNW', // Must match Amazon catalog
'name': 'Wireless Bluetooth Headphones',
'sku': 'SKU-12345',
'asin': 'B08N5WRWNW', // Amazon Standard Identification Number
'brand': 'AudioBrand',
'category': 'Electronics/Audio/Headphones',
'price': 79.99,
'currency': 'USD',
'availability': 'in_stock', // in_stock, out_of_stock, preorder
'rating': 4.5,
'reviewCount': 1234,
'variant': {
'color': 'Black',
'size': 'One Size'
}
}
});
Cart Data Layer
Required on shopping cart pages:
dataLayer.push({
'pageType': 'cart',
'cart': {
'totalValue': 159.98,
'currency': 'USD',
'itemCount': 2,
'products': [
{
'id': 'ASIN-B08N5WRWNW',
'name': 'Wireless Bluetooth Headphones',
'sku': 'SKU-12345',
'price': 79.99,
'quantity': 2,
'category': 'Electronics/Audio/Headphones',
'brand': 'AudioBrand'
}
]
}
});
Transaction Data Layer
Required on order confirmation pages:
dataLayer.push({
'pageType': 'confirmation',
'event': 'purchase',
'transaction': {
'orderId': 'ORDER-2024-67890', // Required: Must be unique
'affiliation': 'Online Store',
'totalValue': 169.98,
'tax': 13.60,
'shipping': 9.99,
'currency': 'USD',
'couponCode': 'SAVE10',
'paymentMethod': 'credit_card',
'products': [
{
'id': 'ASIN-B08N5WRWNW',
'name': 'Wireless Bluetooth Headphones',
'sku': 'SKU-12345',
'asin': 'B08N5WRWNW',
'price': 79.99,
'quantity': 2,
'category': 'Electronics/Audio/Headphones',
'brand': 'AudioBrand',
'variant': 'Black'
}
]
}
});
Campaign Attribution Variables
Capture from URL parameters for Amazon Attribution:
// Extract UTM parameters and Amazon-specific parameters
function getCampaignData() {
var params = new URLSearchParams(window.location.search);
return {
'source': params.get('utm_source'),
'medium': params.get('utm_medium'),
'campaign': params.get('utm_campaign'),
'content': params.get('utm_content'),
'term': params.get('utm_term'),
'amazonTag': params.get('tag'), // Amazon Attribution tag
'clickId': params.get('amzn_click_id') // Amazon click identifier
};
}
dataLayer.push({
'campaign': getCampaignData()
});
Governance Notes
Consent Management Integration
Data layer must reflect user consent state and conditionally populate variables:
// Check consent before populating advertising-related data
function buildDataLayer() {
var baseLayer = {
'pageType': getPageType(),
'siteEnvironment': 'production'
};
// Get consent state from CMP (Consent Management Platform)
var consent = getConsentState();
if (consent.advertising) {
// Include advertising identifiers only if consent granted
baseLayer.advertisingId = getAdvertisingId();
baseLayer.amazonUserId = getAmazonUserId();
}
if (consent.analytics) {
// Include analytics data if consent granted
baseLayer.sessionId = getSessionId();
baseLayer.pageViewCount = getPageViewCount();
}
return baseLayer;
}
dataLayer.push(buildDataLayer());
Privacy-Compliant Product Data
For users who decline advertising consent:
function getProductData(includePersonalization) {
var productData = {
'id': 'ASIN-B08N5WRWNW',
'name': 'Wireless Bluetooth Headphones',
'price': 79.99,
'currency': 'USD'
};
if (includePersonalization) {
// Only include personalization data if consent granted
productData.recommendationId = 'REC-12345';
productData.viewHistory = getUserViewHistory();
}
return productData;
}
Regional Compliance
Adjust data layer based on user location:
function getComplianceSettings(userRegion) {
var settings = {
'region': userRegion,
'gdprApplies': false,
'ccpaApplies': false
};
// EU regions require GDPR compliance
if (['GB', 'DE', 'FR', 'IT', 'ES'].includes(userRegion)) {
settings.gdprApplies = true;
settings.requiresExplicitConsent = true;
}
// California requires CCPA compliance
if (userRegion === 'US-CA') {
settings.ccpaApplies = true;
settings.requiresOptOut = true;
}
return settings;
}
dataLayer.push({
'compliance': getComplianceSettings(userRegion)
});
Data Layer Versioning
Maintain version control for schema changes:
dataLayer.push({
'dataLayerVersion': '2.1.0', // Semantic versioning
'schemaDate': '2025-01-15', // Last schema update
'implementation': {
'method': 'gtm', // gtm, tealium, segment, custom
'version': '1.2.3'
}
});
Validation Steps
Pre-Launch Data Layer Audit
Schema Validation
Create a validation function to check data layer completeness:
function validateDataLayer() {
var errors = [];
var warnings = [];
// Check required fields
if (!dataLayer.find(obj => obj.pageType)) {
errors.push('Missing required field: pageType');
}
// Check transaction data on confirmation pages
if (dataLayer.find(obj => obj.pageType === 'confirmation')) {
var transaction = dataLayer.find(obj => obj.transaction);
if (!transaction) {
errors.push('Transaction page missing transaction object');
} else {
if (!transaction.orderId) errors.push('Missing transaction.orderId');
if (!transaction.totalValue) errors.push('Missing transaction.totalValue');
if (!transaction.currency) errors.push('Missing transaction.currency');
if (!transaction.products || transaction.products.length === 0) {
errors.push('Missing or empty transaction.products array');
}
}
}
// Check product data format
var products = dataLayer.filter(obj => obj.product || obj.products);
products.forEach(function(obj) {
var productArray = obj.products || [obj.product];
productArray.forEach(function(product) {
if (!product.id) warnings.push('Product missing id field');
if (!product.price || typeof product.price !== 'number') {
errors.push('Product price must be numeric');
}
});
});
return {
valid: errors.length === 0,
errors: errors,
warnings: warnings
};
}
// Run validation in dev/staging environments
if (dataLayer.find(obj => obj.siteEnvironment !== 'production')) {
var validation = validateDataLayer();
console.log('Data Layer Validation:', validation);
}
Browser Console Testing
Test data layer in browser developer console:
// View current data layer
console.table(dataLayer);
// Filter for specific page types
console.log('Transaction Data:',
dataLayer.filter(obj => obj.transaction)
);
// Check for required fields
console.log('Has Order ID?',
dataLayer.some(obj => obj.transaction && obj.transaction.orderId)
);
Integration Testing
GTM Data Layer Variables
Verify GTM can access data layer variables:
- Enable GTM Preview Mode
- Navigate to page with data layer
- Click on page in Preview pane
- Check "Data Layer" tab
- Verify all expected variables present with correct values
Amazon Pixel Payload Verification
Confirm data flows from data layer to Amazon pixel:
// In GTM, create Amazon Ads tag with console logging
<script>
console.log('Amazon Pixel Data:', {
orderId: {{DLV - Order ID}},
value: {{DLV - Transaction Value}},
currency: {{DLV - Currency}},
products: {{DLV - Products}}
});
aw('conversion', {
transactionId: {{DLV - Order ID}},
value: {{DLV - Transaction Value}},
currency: {{DLV - Currency}},
products: {{DLV - Products}}
});
</script>
Automated Testing
Unit Tests for Data Layer Functions
describe('Data Layer Functions', function() {
it('should extract campaign parameters from URL', function() {
var testUrl = '?utm_source=amazon&utm_campaign=summer_sale';
var campaignData = getCampaignData(testUrl);
expect(campaignData.source).toBe('amazon');
expect(campaignData.campaign).toBe('summer_sale');
});
it('should format product data correctly', function() {
var product = getProductData(true);
expect(product).toHaveProperty('id');
expect(product).toHaveProperty('price');
expect(typeof product.price).toBe('number');
});
it('should respect consent settings', function() {
var dataLayer = buildDataLayer(false); // advertising consent denied
expect(dataLayer).not.toHaveProperty('advertisingId');
});
});
E2E Testing
Use Cypress or Selenium to validate data layer across user journeys:
// Cypress test example
describe('E-commerce Flow Data Layer', function() {
it('should populate transaction data on purchase', function() {
cy.visit('/product/ASIN-B08N5WRWNW');
cy.get('[data-testid="add-to-cart"]').click();
cy.visit('/cart');
cy.get('[data-testid="checkout"]').click();
// Fill out checkout form
cy.get('[name="email"]').type('test@example.com');
cy.get('[name="card"]').type('4111111111111111');
cy.get('[data-testid="place-order"]').click();
// Verify data layer on confirmation page
cy.window().then((win) => {
const transaction = win.dataLayer.find(obj => obj.transaction);
expect(transaction).to.exist;
expect(transaction.orderId).to.exist;
expect(transaction.totalValue).to.be.greaterThan(0);
expect(transaction.products).to.have.length.greaterThan(0);
});
});
});
Data Quality Monitoring
Production Monitoring
Implement runtime checks in production:
// Monitor data layer quality in production
(function() {
var missingFields = [];
window.addEventListener('load', function() {
// Check critical fields based on page type
var pageType = dataLayer.find(obj => obj.pageType);
if (pageType === 'confirmation') {
var transaction = dataLayer.find(obj => obj.transaction);
if (!transaction || !transaction.orderId) {
missingFields.push('transaction.orderId');
// Send error to monitoring service
sendToAnalytics('data_layer_error', {
page: window.location.pathname,
missingFields: missingFields
});
}
}
});
})();
Alerting Thresholds
Configure alerts for data quality issues:
- Alert if >5% of transactions missing orderId in past hour
- Alert if product prices are non-numeric >1% of the time
- Alert if consent state undefined on >10% of page loads
- Alert if data layer version mismatches across site pages