DataLayer Spec Generator
Copy-paste-ready dataLayer events for the most common site types — eComm, lead-gen, SaaS — wired up so GA4, Meta CAPI, and Google Ads Enhanced Conversions all work from the same push.
Site type
view_itemwindow.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: "view_item",
ecommerce: {
currency: "USD",
value: 79.00,
items: [{
item_id: "SKU_12345",
item_name: "Merino Crew Sweater",
item_brand: "Northwind",
item_category: "Apparel",
item_variant: "Black",
price: 79.00,
quantity: 1
}]
}
});add_to_cartwindow.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: "add_to_cart",
ecommerce: {
currency: "USD",
value: 79.00,
items: [{
item_id: "SKU_12345",
item_name: "Merino Crew Sweater",
price: 79.00,
quantity: 1
}]
}
});begin_checkoutwindow.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: "begin_checkout",
ecommerce: {
currency: "USD",
value: 158.00,
items: [/* same items array */]
}
});purchase (with user data for CAPI / EC)window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: "purchase",
user_data: {
email: "ada@example.com", // hash server-side before sending to platforms
phone: "+12025550100",
first_name: "Ada",
last_name: "Lovelace",
address: { city: "London", postal_code: "SW1A 1AA", country: "GB" }
},
ecommerce: {
transaction_id: "ORD_98765", // critical for de-dup
currency: "USD",
value: 158.00,
tax: 12.00,
shipping: 5.00,
coupon: "SPRING10",
items: [/* full items array */]
}
});Why ecommerce: null first? GA4's ecommerce object persists across pushes. Resetting it prevents stale items from leaking into the next event.
The user_data block lives at the dataLayer level (not inside ecommerce) so a single GTM tag can pick it up for both Meta CAPI and Google Enhanced Conversions.
