This guide covers setting up a proper data layer structure for Taboola event tracking, including event parameters, data formatting, and best practices.
Data Layer Overview
A data layer provides a structured way to store and pass information to the Taboola Pixel. It ensures:
- Consistent data formatting across pages
- Clean separation of data from tracking code
- Easy maintenance and updates
- Reliable event tracking
Basic Data Layer Structure
Simple Data Layer
window.taboolaData = {
accountId: 1234567,
pageType: 'product',
productId: 'PROD_123',
productPrice: 99.99,
currency: 'USD'
};
Comprehensive Data Layer
window.taboolaData = {
// Account configuration
accountId: 1234567,
// Page information
page: {
type: 'product', // home, category, product, cart, checkout, confirmation
url: window.location.href,
title: document.title,
referrer: document.referrer
},
// Product information (e-commerce)
product: {
id: 'PROD_123',
name: 'Wireless Headphones',
price: 99.99,
category: 'Electronics > Audio',
brand: 'AudioBrand',
availability: 'in stock'
},
// User information
user: {
id: 'USER_789',
status: 'logged_in', // logged_in, guest
type: 'returning' // new, returning
},
// Transaction information (confirmation page)
transaction: {
id: 'ORDER_12345',
total: 199.98,
subtotal: 189.99,
tax: 9.99,
shipping: 10.00,
currency: 'USD',
items: [
{
id: 'PROD_123',
name: 'Wireless Headphones',
price: 99.99,
quantity: 2
}
]
}
};
Event-Specific Data Layers
Product Page Data Layer
window.taboolaData = {
accountId: 1234567,
page: {
type: 'product'
},
product: {
id: 'SHOE_BLK_10',
name: 'Running Shoes - Black',
price: 79.99,
originalPrice: 99.99, // If on sale
category: 'Shoes > Running',
brand: 'Nike',
availability: 'in stock',
imageUrl: 'https://example.com/images/shoe.jpg',
sku: 'SKU_789'
}
};
// Track product view
window._tfa = window._tfa || [];
window._tfa.push({
notify: 'event',
name: 'view_content',
id: window.taboolaData.accountId,
content_id: window.taboolaData.product.id,
content_type: 'product',
value: window.taboolaData.product.price
});
Shopping Cart Data Layer
window.taboolaData = {
accountId: 1234567,
page: {
type: 'cart'
},
cart: {
items: [
{
id: 'PROD_123',
name: 'Wireless Headphones',
price: 99.99,
quantity: 1
},
{
id: 'PROD_456',
name: 'Phone Case',
price: 19.99,
quantity: 2
}
],
subtotal: 139.97,
itemCount: 3
}
};
// Track add to cart
function trackAddToCart(productId, price) {
window._tfa.push({
notify: 'event',
name: 'add_to_cart',
id: window.taboolaData.accountId,
content_id: productId,
value: price,
currency: 'USD'
});
}
Order Confirmation Data Layer
window.taboolaData = {
accountId: 1234567,
page: {
type: 'confirmation'
},
transaction: {
id: 'ORDER_2024_001234',
total: 159.97,
subtotal: 139.97,
tax: 10.00,
shipping: 10.00,
currency: 'USD',
items: [
{
id: 'PROD_123',
name: 'Wireless Headphones',
price: 99.99,
quantity: 1,
category: 'Electronics'
},
{
id: 'PROD_456',
name: 'Phone Case',
price: 19.99,
quantity: 2,
category: 'Accessories'
}
],
paymentMethod: 'credit_card',
shippingMethod: 'standard'
}
};
// Track purchase
window._tfa = window._tfa || [];
window._tfa.push({
notify: 'event',
name: 'make_purchase',
id: window.taboolaData.accountId,
revenue: window.taboolaData.transaction.total,
currency: window.taboolaData.transaction.currency,
order_id: window.taboolaData.transaction.id
});
Content Publisher Data Layer
Article Page
window.taboolaData = {
accountId: 1234567,
page: {
type: 'article'
},
content: {
id: 'ARTICLE_789',
title: 'How to Choose Running Shoes',
category: 'Sports > Running',
author: 'John Doe',
publishDate: '2024-01-15',
wordCount: 1500,
tags: ['running', 'fitness', 'shoes']
}
};
// Track article view
window._tfa.push({
notify: 'event',
name: 'view_content',
id: window.taboolaData.accountId,
content_id: window.taboolaData.content.id,
content_type: 'article'
});
Video Page
window.taboolaData = {
accountId: 1234567,
page: {
type: 'video'
},
video: {
id: 'VIDEO_456',
title: 'Product Demo - Wireless Headphones',
duration: 180, // seconds
category: 'Product Reviews',
publishDate: '2024-01-20'
}
};
// Track video view
window._tfa.push({
notify: 'event',
name: 'view_content',
id: window.taboolaData.accountId,
content_id: window.taboolaData.video.id,
content_type: 'video'
});
Data Layer Helper Functions
Initialize Data Layer
// Initialize data layer on page load
(function() {
window.taboolaData = window.taboolaData || {};
// Set defaults
window.taboolaData.accountId = window.taboolaData.accountId || 1234567;
window.taboolaData.page = window.taboolaData.page || {};
window.taboolaData.page.url = window.location.href;
window.taboolaData.page.title = document.title;
window.taboolaData.page.referrer = document.referrer;
})();
Get Data Layer Value
function getTaboolaData(path, defaultValue = null) {
const keys = path.split('.');
let value = window.taboolaData;
for (const key of keys) {
if (value && typeof value === 'object' && key in value) {
value = value[key];
} else {
return defaultValue;
}
}
return value;
}
// Usage
const productId = getTaboolaData('product.id');
const pageType = getTaboolaData('page.type', 'unknown');
const revenue = getTaboolaData('transaction.total', 0);
Set Data Layer Value
function setTaboolaData(path, value) {
const keys = path.split('.');
let obj = window.taboolaData;
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (!(key in obj) || typeof obj[key] !== 'object') {
obj[key] = {};
}
obj = obj[key];
}
obj[keys[keys.length - 1]] = value;
}
// Usage
setTaboolaData('product.id', 'PROD_789');
setTaboolaData('user.id', 'USER_123');
Dynamic Data Layer Updates
Update on User Action
// Add to cart button click
document.querySelectorAll('.add-to-cart').forEach(button => {
button.addEventListener('click', function() {
const productId = this.dataset.productId;
const productPrice = parseFloat(this.dataset.productPrice);
// Update data layer
if (!window.taboolaData.cart) {
window.taboolaData.cart = { items: [] };
}
window.taboolaData.cart.items.push({
id: productId,
price: productPrice,
quantity: 1
});
// Track event
window._tfa.push({
notify: 'event',
name: 'add_to_cart',
id: window.taboolaData.accountId,
content_id: productId,
value: productPrice,
currency: 'USD'
});
});
});
Single Page Application Updates
// Update data layer on route change
function updateDataLayerOnRouteChange(newRoute) {
// Clear previous page data
window.taboolaData.page = {};
window.taboolaData.product = {};
window.taboolaData.content = {};
// Set new page data
window.taboolaData.page.type = determinePageType(newRoute);
window.taboolaData.page.url = newRoute;
// Track page view
window._tfa.push({
notify: 'event',
name: 'page_view',
id: window.taboolaData.accountId
});
}
function determinePageType(url) {
if (url.includes('/product/')) return 'product';
if (url.includes('/cart')) return 'cart';
if (url.includes('/checkout')) return 'checkout';
if (url.includes('/order-confirmation')) return 'confirmation';
return 'page';
}
Server-Side Data Layer Generation
PHP Example
<?php
// Generate data layer from server-side data
$product = getProduct($productId);
?>
<script>
window.taboolaData = {
accountId: <?php echo TABOOLA_ACCOUNT_ID; ?>,
page: {
type: 'product'
},
product: {
id: '<?php echo htmlspecialchars($product['id']); ?>',
name: '<?php echo htmlspecialchars($product['name']); ?>',
price: <?php echo floatval($product['price']); ?>,
category: '<?php echo htmlspecialchars($product['category']); ?>',
brand: '<?php echo htmlspecialchars($product['brand']); ?>',
availability: '<?php echo $product['in_stock'] ? 'in stock' : 'out of stock'; ?>'
}
};
</script>
Node.js/Express Example
// Express route
app.get('/product/:id', async (req, res) => {
const product = await getProduct(req.params.id);
const taboolaData = {
accountId: process.env.TABOOLA_ACCOUNT_ID,
page: {
type: 'product'
},
product: {
id: product.id,
name: product.name,
price: product.price,
category: product.category,
brand: product.brand,
availability: product.inStock ? 'in stock' : 'out of stock'
}
};
res.render('product', {
product,
taboolaData: JSON.stringify(taboolaData)
});
});
// In template
<script>
window.taboolaData = {{{taboolaData}}};
</script>
Data Validation
Validate Data Before Tracking
function validatePurchaseData(data) {
const errors = [];
if (!data.order_id) {
errors.push('Missing order_id');
}
if (typeof data.revenue !== 'number' || data.revenue <= 0) {
errors.push('Invalid revenue value');
}
if (!data.currency || !/^[A-Z]{3}$/.test(data.currency)) {
errors.push('Invalid currency code');
}
return {
valid: errors.length === 0,
errors: errors
};
}
// Usage
function trackPurchase() {
const purchaseData = {
order_id: window.taboolaData.transaction.id,
revenue: window.taboolaData.transaction.total,
currency: window.taboolaData.transaction.currency
};
const validation = validatePurchaseData(purchaseData);
if (!validation.valid) {
console.error('Purchase tracking validation failed:', validation.errors);
return;
}
window._tfa.push({
notify: 'event',
name: 'make_purchase',
id: window.taboolaData.accountId,
...purchaseData
});
}
Data Type Conversion
function sanitizeTaboolaData(data) {
return {
accountId: parseInt(data.accountId),
revenue: parseFloat(data.revenue),
currency: String(data.currency).toUpperCase(),
order_id: String(data.order_id),
value: data.value ? parseFloat(data.value) : undefined
};
}
// Usage
const rawData = {
accountId: "1234567",
revenue: "99.99",
currency: "usd",
order_id: 12345
};
const cleanData = sanitizeTaboolaData(rawData);
// {
// accountId: 1234567,
// revenue: 99.99,
// currency: "USD",
// order_id: "12345"
// }
Google Tag Manager Integration
GTM Data Layer to Taboola
// Listen to GTM data layer
window.dataLayer = window.dataLayer || [];
window.dataLayer.push = function(...args) {
Array.prototype.push.apply(this, args);
// Process each pushed item
args.forEach(item => {
// Purchase event
if (item.event === 'purchase') {
window._tfa.push({
notify: 'event',
name: 'make_purchase',
id: 1234567,
revenue: item.ecommerce.purchase.actionField.revenue,
currency: item.ecommerce.currencyCode,
order_id: item.ecommerce.purchase.actionField.id
});
}
// Add to cart event
if (item.event === 'addToCart') {
const product = item.ecommerce.add.products[0];
window._tfa.push({
notify: 'event',
name: 'add_to_cart',
id: 1234567,
content_id: product.id,
value: product.price,
currency: item.ecommerce.currencyCode
});
}
});
};
Best Practices
1. Consistent Structure
Use the same data layer structure across all pages:
// Define standard structure
const TABOOLA_DATA_TEMPLATE = {
accountId: null,
page: {
type: null,
url: null,
title: null
},
product: null,
content: null,
transaction: null,
user: null
};
// Initialize with template
window.taboolaData = Object.assign({}, TABOOLA_DATA_TEMPLATE, {
accountId: 1234567
});
2. Data Privacy
Hash personal information:
async function hashEmail(email) {
const msgBuffer = new TextEncoder().encode(email.toLowerCase().trim());
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// Store hashed data
window.taboolaData.user = {
id: await hashEmail(userEmail),
status: 'logged_in'
};
3. Data Layer Loading Order
Ensure data layer loads before tracking:
<!-- 1. Initialize data layer -->
<script>
window.taboolaData = {
accountId: 1234567,
page: { type: 'product' },
product: { id: 'PROD_123', price: 99.99 }
};
</script>
<!-- 2. Load Taboola Pixel -->
<script src="//cdn.taboola.com/libtrc/unip/1234567/tfa.js" async></script>
<!-- 3. Track events -->
<script>
window._tfa = window._tfa || [];
window._tfa.push({
notify: 'event',
name: 'view_content',
id: window.taboolaData.accountId,
content_id: window.taboolaData.product.id,
value: window.taboolaData.product.price
});
</script>
4. Document Data Layer Schema
/**
* Taboola Data Layer Schema
*
* @typedef {Object} TaboolaData
* @property {number} accountId - Taboola account ID
* @property {Object} page - Page information
* @property {string} page.type - Page type (product, cart, checkout, etc.)
* @property {Object} [product] - Product information (for product pages)
* @property {string} product.id - Product ID
* @property {number} product.price - Product price
* @property {Object} [transaction] - Transaction information (for confirmation pages)
* @property {string} transaction.id - Order ID
* @property {number} transaction.total - Order total
* @property {string} transaction.currency - Currency code
*/
Debugging Data Layer
Console Inspection
// View current data layer
console.log('Taboola Data Layer:', window.taboolaData);
// View specific values
console.log('Product ID:', window.taboolaData?.product?.id);
console.log('Page Type:', window.taboolaData?.page?.type);
console.log('Transaction Total:', window.taboolaData?.transaction?.total);
Data Layer Monitor
// Monitor data layer changes
const taboolaDataProxy = new Proxy(window.taboolaData, {
set(target, property, value) {
console.log(`Data layer updated: ${property} =`, value);
target[property] = value;
return true;
}
});
window.taboolaData = taboolaDataProxy;
Next Steps
- Event Tracking - Implement conversion events
- Cross-Domain Tracking - Track across domains
- Troubleshooting - Debug data layer issues