Why the DataLayer Is the Foundation of Your E-commerce Tracking
The dataLayer is a JavaScript object that serves as the bridge between your website and Google Tag Manager (GTM). Without it, your tags have no access to business data: no product name, no price, no category, no revenue.
What we see in the field: across 150+ e-commerce audits over the past 3 years, 72% had an incomplete or poorly structured dataLayer. The result: unusable GA4 reports, ad campaigns optimizing on bad data, and business decisions made blind.
This guide gives you everything you need to implement a GA4-compliant e-commerce dataLayer on any platform.
The GA4 E-commerce Specification: Required Events
GA4 expects a structured series of events to reconstruct the purchase funnel. Here are the essential events and their required parameters:
1. view_item — Product Page Viewed
dataLayer.push({
event: "view_item",
ecommerce: {
currency: "EUR",
value: 49.90,
items: [{
item_id: "SKU-12345",
item_name: "Organic Crew Neck T-shirt",
item_brand: "MyBrand",
item_category: "Clothing",
item_category2: "T-shirts",
item_variant: "Blue / M",
price: 49.90,
quantity: 1,
index: 0
}]
}
});
2. add_to_cart — Item Added to Cart
dataLayer.push({
event: "add_to_cart",
ecommerce: {
currency: "EUR",
value: 49.90,
items: [{
item_id: "SKU-12345",
item_name: "Organic Crew Neck T-shirt",
item_brand: "MyBrand",
item_category: "Clothing",
item_variant: "Blue / M",
price: 49.90,
quantity: 1
}]
}
});
3. begin_checkout — Checkout Started
dataLayer.push({
event: "begin_checkout",
ecommerce: {
currency: "EUR",
value: 149.70,
coupon: "SAVE10",
items: [
{
item_id: "SKU-12345",
item_name: "Organic Crew Neck T-shirt",
price: 49.90,
quantity: 3
}
]
}
});
4. purchase — Transaction Completed
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "T-20260511-001",
currency: "EUR",
value: 149.70,
tax: 24.95,
shipping: 4.90,
coupon: "SAVE10",
items: [
{
item_id: "SKU-12345",
item_name: "Organic Crew Neck T-shirt",
item_brand: "MyBrand",
item_category: "Clothing",
item_variant: "Blue / M",
price: 49.90,
quantity: 3
}
]
}
});
Additional Important Events
| Event | When to Trigger | Key Parameters |
|---|---|---|
view_item_list | Category page, search results | item_list_id, item_list_name, items[] |
select_item | Click on a product in a list | item_list_id, items[] |
remove_from_cart | Product removed from cart | currency, value, items[] |
add_shipping_info | Shipping method selected | shipping_tier, currency, value, items[] |
add_payment_info | Payment information entered | payment_type, currency, value, items[] |
Platform-Specific Implementation
Shopify
Shopify offers several approaches:
Option 1: Via theme.liquid (full control)
Inject the dataLayer directly in your Liquid templates. Example for the product page:
{% if template contains 'product' %}
<script>
dataLayer.push({ ecommerce: null }); // Clear previous
dataLayer.push({
event: "view_item",
ecommerce: {
currency: "{{ shop.currency }}",
value: {{ product.selected_or_first_available_variant.price | money_without_currency | remove: ',' }},
items: [{
item_id: "{{ product.selected_or_first_available_variant.sku }}",
item_name: "{{ product.title | escape }}",
item_brand: "{{ product.vendor | escape }}",
item_category: "{{ product.type | escape }}",
price: {{ product.selected_or_first_available_variant.price | money_without_currency | remove: ',' }},
quantity: 1
}]
}
});
</script>
{% endif %}
Option 2: Via a Shopify app (Elevar, DataLayer Pro, littledata). Faster to set up but less control. Cost: EUR 100-300/month depending on the app.
Shopify caveat: the checkout is locked on non-Plus plans. Use additional checkout scripts or the Web Pixel API for begin_checkout and purchase events.
PrestaShop
Option 1: Dedicated module (GTM4PS, Advanced Google Tag Manager). Good coverage of base events, back-office configuration.
Option 2: Custom development using hooks
PrestaShop uses a hook system. Relevant hooks:
| Hook | DataLayer Event |
|---|---|
displayHeader | DataLayer initialization |
displayProductActions | view_item |
actionCartSave | add_to_cart |
displayOrderConfirmation | purchase |
// Example in a custom module - hookDisplayOrderConfirmation
public function hookDisplayOrderConfirmation($params)
{
$order = $params['order'];
$products = $order->getProducts();
// Build the items[] array and inject JS
}
WooCommerce
Option 1: Plugin (GTM4WP by Thomas Geiger — free and reliable, or the official Google Listings & Ads plugin).
Option 2: Custom code in functions.php
// Example: dataLayer push on the confirmation page
add_action('woocommerce_thankyou', function($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
$items = [];
foreach ($order->get_items() as $item) {
$product = $item->get_product();
$items[] = [
'item_id' => $product->get_sku(),
'item_name' => $item->get_name(),
'price' => (float) $order->get_item_total($item),
'quantity' => $item->get_quantity(),
];
}
$data = [
'event' => 'purchase',
'ecommerce' => [
'transaction_id' => (string) $order->get_id(),
'value' => (float) $order->get_total(),
'currency' => $order->get_currency(),
'tax' => (float) $order->get_total_tax(),
'shipping' => (float) $order->get_shipping_total(),
'items' => $items,
],
];
echo '<script>dataLayer.push(' . json_encode($data) . ');</script>';
});
The Most Common Mistakes (and How to Avoid Them)
1. Missing Currency (currency)
Impact: without currency, GA4 cannot calculate revenue. Your monetary reports show EUR 0. This is the most destructive and most common error — it renders 100% of your revenue data unusable.
2. Incorrect Event Names
GA4 expects exact names: add_to_cart, not addToCart, not Add_To_Cart, not add-to-cart. Any variation creates a custom event instead of feeding the standard e-commerce reports.
3. Inconsistent items[] Array
The classic trap: item_id is the SKU on the product page but the product ID in the cart. Or price is tax-inclusive on view_item but tax-exclusive on purchase. Ensure the same logic applies across the entire funnel.
4. Forgetting to Clear the DataLayer
Before each e-commerce push, clear the ecommerce object:
dataLayer.push({ ecommerce: null });
Without this, data from the previous event can persist and contaminate the next one.
5. Duplicate purchase Push
If your confirmation page reloads (back button, refresh), the same purchase is counted twice. Implement a guard based on transaction_id using sessionStorage or localStorage.
Testing Your Implementation
GTM Preview Mode
- Open GTM > Preview > enter your site URL
- Navigate through the purchase funnel
- In the debug panel, check each event: are variables populated? Are tags firing?
GA4 DebugView
- In GA4 > Admin > DebugView
- Each event appears in real time with its parameters
- Verify that
items,value,currency, andtransaction_idare present and correct
Pre-Launch Checklist
- All funnel events are present (
view_item->add_to_cart->begin_checkout->purchase) -
currencyis sent with every monetary event -
item_idanditem_nameare consistent across the entire funnel -
transaction_idis unique per order - DataLayer is cleared (
ecommerce: null) before each push - Prices are numbers (not strings)
- The
purchasepush fires only once per order
Need a Reliable DataLayer?
A poorly implemented dataLayer means months of unusable data and campaigns optimizing in the dark. At chillmetrics, we install and validate your e-commerce tracking on every platform, with a documented tagging plan and rigorous testing.
Let us handle your tracking installation and start making decisions based on reliable data.