Data Layer Overview
A properly structured data layer enables dynamic Spotify Pixel event firing with accurate attribution data for audio, video, and podcast campaigns.
Base Structure
window.spotifyDataLayer = window.spotifyDataLayer || {
page: {},
user: {},
product: {},
transaction: {},
attribution: {}
};
Page Data
window.spotifyDataLayer.page = {
type: 'homepage',
category: 'main',
url: window.location.href,
referrer: document.referrer
};
Attribution Data
UTM Parameters
window.spotifyDataLayer.attribution = {
source: new URLSearchParams(window.location.search).get('utm_source'),
medium: new URLSearchParams(window.location.search).get('utm_medium'),
campaign: new URLSearchParams(window.location.search).get('utm_campaign'),
isSpotify: new URLSearchParams(window.location.search).get('utm_source') === 'spotify'
};
// Store Spotify attribution
if (window.spotifyDataLayer.attribution.isSpotify) {
sessionStorage.setItem('spotify_attribution', JSON.stringify(window.spotifyDataLayer.attribution));
}
Promo Code Data
window.spotifyDataLayer.promoCode = {
code: null,
applied: false,
discountAmount: 0,
source: null
};
function applyPromoCode(code) {
if (code.toUpperCase().startsWith('SPOTIFY')) {
window.spotifyDataLayer.promoCode = {
code: code.toUpperCase(),
applied: true,
discountAmount: calculateDiscount(code),
source: 'spotify_audio_ad'
};
spotify('track', 'CustomEvent', {
event_name: 'promo_code_applied',
code: code.toUpperCase()
});
}
}
E-commerce Data
Product Data
window.spotifyDataLayer.product = {
id: 'SKU_12345',
name: 'Blue Widget',
price: 49.99,
category: 'widgets',
brand: 'WidgetCo'
};
// Fire Spotify event
spotify('track', 'ViewContent', {
product_id: window.spotifyDataLayer.product.id,
value: window.spotifyDataLayer.product.price,
currency: 'USD'
});
Transaction Data
window.spotifyDataLayer.transaction = {
id: 'ORDER_12345',
revenue: 176.97,
tax: 12.00,
shipping: 5.00,
currency: 'USD',
promoCode: window.spotifyDataLayer.promoCode.code,
items: [
{ id: 'SKU_12345', name: 'Blue Widget', price: 49.99, quantity: 2 }
]
};
// Fire purchase event
spotify('track', 'Purchase', {
value: window.spotifyDataLayer.transaction.revenue,
currency: window.spotifyDataLayer.transaction.currency,
order_id: window.spotifyDataLayer.transaction.id,
promo_code: window.spotifyDataLayer.transaction.promoCode
});
Helper Functions
function fireSpotifyEventFromDataLayer(eventName) {
let eventData = {};
switch(eventName) {
case 'Purchase':
eventData = {
value: window.spotifyDataLayer.transaction?.revenue,
currency: 'USD',
order_id: window.spotifyDataLayer.transaction?.id,
promo_code: window.spotifyDataLayer.promoCode?.code
};
break;
case 'Lead':
eventData = {
lead_type: window.spotifyDataLayer.form?.type,
value: 50.00
};
break;
}
if (typeof spotify !== 'undefined') {
spotify('track', eventName, eventData);
}
}
Best Practices
- Initialize data layer before Spotify Pixel
- Track UTM parameters for attribution
- Store promo codes in sessionStorage
- Clear data layer on SPA navigation
- Validate data before firing events
- Document schema for team