Data Layer Overview
A data layer is a JavaScript object that stores structured information about the page, user, and transactions. The Trade Desk Universal Pixel consumes data layer values to populate event parameters dynamically, enabling accurate conversion tracking and audience segmentation.
Standard Data Layer Structure
Basic Data Layer Object
Create a data layer before Universal Pixel loads:
window.ttdDataLayer = window.ttdDataLayer || {
page: {
type: 'product',
category: 'electronics',
url: window.location.href,
title: document.title
},
user: {
status: 'logged_in',
tier: 'premium',
id: 'USER12345'
}
};
E-commerce Data Layer
window.ttdDataLayer = {
page: {
type: 'purchase_confirmation',
category: 'checkout'
},
transaction: {
id: 'ORD789456',
total: 349.99,
currency: 'USD',
shipping: 15.00,
tax: 28.75,
subtotal: 306.24
},
products: [
{
id: 'SKU123',
name: 'Wireless Headphones',
category: 'Electronics/Audio',
brand: 'AudioBrand',
price: 149.99,
quantity: 2
},
{
id: 'SKU456',
name: 'Phone Case',
category: 'Accessories',
brand: 'CaseBrand',
price: 29.99,
quantity: 2
}
],
user: {
status: 'returning',
tier: 'gold',
email_hash: 'abc123def456', // SHA-256 hash for UID2
id: 'CUSTOMER123'
},
marketing: {
campaign: 'spring_sale_2024',
source: 'email',
medium: 'newsletter',
promo_code: 'SPRING20'
}
};
Integrating Data Layer with Universal Pixel
Pull Values from Data Layer
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'purchase',
value: window.ttdDataLayer.transaction.total,
currency: window.ttdDataLayer.transaction.currency,
order_id: window.ttdDataLayer.transaction.id,
items: window.ttdDataLayer.products.map(product => ({
item_id: product.id,
item_name: product.name,
category: product.category,
price: product.price,
quantity: product.quantity
})),
td2: window.ttdDataLayer.user.tier,
td3: window.ttdDataLayer.marketing.campaign,
td4: window.ttdDataLayer.marketing.source
});
GTM Variable Mapping
Create Data Layer Variables in GTM:
Transaction Total:
- Variable Type: Data Layer Variable
- Data Layer Variable Name:
ttdDataLayer.transaction.total
Transaction ID:
- Variable Type: Data Layer Variable
- Data Layer Variable Name:
ttdDataLayer.transaction.id
User Tier:
- Variable Type: Data Layer Variable
- Data Layer Variable Name:
ttdDataLayer.user.tier
Use variables in Universal Pixel tag:
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'purchase',
value: {{DL - Transaction Total}},
currency: 'USD',
order_id: {{DL - Transaction ID}},
td2: {{DL - User Tier}}
});
UID2 Data Layer Integration
Client-Side UID2 Token
window.ttdDataLayer = {
user: {
email_hash: generateSHA256(userEmail), // Client-side hash
uid2_token: null // Populated by UID2 SDK
}
};
// After UID2 token generation
window.ttdDataLayer.user.uid2_token = uid2Token;
// Pass to Universal Pixel
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
uid2_token: window.ttdDataLayer.user.uid2_token,
event_name: 'page_view'
});
Server-Side UID2 Token
Inject token from server template:
<script>
window.ttdDataLayer = {
user: {
uid2_token: '<%= uid2_token_from_server %>'
}
};
</script>
<script>
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
uid2_token: window.ttdDataLayer.user.uid2_token,
event_name: 'page_view'
});
</script>
Dynamic Product Data Layers
Product Detail Page
window.ttdDataLayer = {
page: {
type: 'product_detail'
},
product: {
id: 'SKU789',
name: 'Premium Laptop',
category: 'Electronics/Computers',
brand: 'TechBrand',
price: 1299.99,
availability: 'in_stock',
image_url: 'https://example.com/images/laptop.jpg',
url: window.location.href
},
user: {
status: 'guest'
}
};
Fire product view event:
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'product_view',
items: [{
item_id: window.ttdDataLayer.product.id,
item_name: window.ttdDataLayer.product.name,
category: window.ttdDataLayer.product.category,
price: window.ttdDataLayer.product.price
}],
td2: window.ttdDataLayer.product.brand,
td3: window.ttdDataLayer.product.availability
});
Category Page
window.ttdDataLayer = {
page: {
type: 'category',
category: 'womens/shoes',
products_shown: 24
},
filters: {
price_range: '50-100',
size: '8',
brand: 'NikeBrand'
}
};
Lead Generation Data Layer
window.ttdDataLayer = {
page: {
type: 'lead_confirmation'
},
lead: {
type: 'contact_form',
source: 'website',
value: 50.00,
form_id: 'contact_us_form'
},
user: {
interest: 'enterprise_solution',
company_size: '100-500',
industry: 'technology'
}
};
Fire lead event:
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'lead',
value: window.ttdDataLayer.lead.value,
lead_type: window.ttdDataLayer.lead.type,
td2: window.ttdDataLayer.user.interest,
td3: window.ttdDataLayer.user.company_size,
td4: window.ttdDataLayer.user.industry
});
Single Page Application (SPA) Data Layer
Update Data Layer on Route Change
// React example
useEffect(() => {
window.ttdDataLayer = {
page: {
type: pageType,
url: window.location.href,
title: document.title
},
user: {
status: user.isLoggedIn ? 'logged_in' : 'guest',
tier: user.tier
}
};
// Fire page view on route change
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'page_view',
page_url: window.ttdDataLayer.page.url,
page_title: window.ttdDataLayer.page.title
});
}, [location.pathname]);
Data Layer Validation
Pre-Launch Checklist
- Data layer populates before Universal Pixel fires
- All required fields have values (not null or undefined)
- Numeric values are numbers, not strings
- Currency values formatted with two decimal places
- Product IDs and order IDs are unique and consistent
- Custom parameters map to meaningful business values
- UID2 tokens generate and refresh correctly
Debugging Data Layer
// Console log data layer for debugging
console.log('TTD Data Layer:', window.ttdDataLayer);
// Verify data layer before pixel fire
if (window.ttdDataLayer && window.ttdDataLayer.transaction) {
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'purchase',
value: window.ttdDataLayer.transaction.total,
order_id: window.ttdDataLayer.transaction.id
});
} else {
console.error('TTD Data Layer not ready');
}
Best Practices
- Initialize data layer before Universal Pixel loads
- Use consistent naming conventions across all pages
- Populate data layer server-side when possible for accuracy
- Validate data types (numbers as numbers, strings as strings)
- Use null or empty string for missing optional values
- Document data layer structure for development team
- Test data layer on staging before production deployment
- Monitor data layer values in production with error tracking
- Keep sensitive PII out of data layer (use hashed values)
- Implement fallback values for critical parameters
- Regular audit of data layer accuracy and completeness
- Use data layer for consistency across multiple platforms (GA4, Meta, etc.)