What Enhanced Ecommerce Tracking Is
Enhanced ecommerce tracking in GA4 means implementing the full set of recommended ecommerce events - not just the purchase event.
When implemented correctly, GA4 gives you:
- Product-level performance data
- Funnel drop-off rates (view → cart → checkout → purchase)
- Revenue attribution by product category
- Audience building based on product interactions
The data layer is the mechanism that passes this data from your website to GTM, and from GTM to GA4.
The Ecommerce Events GA4 Recommends
These are the standard ecommerce events with their recommended parameters:
| Event | When to Fire |
|---|---|
view_item_list | Product category or search results page |
select_item | User clicks a product from a list |
view_item | Product detail page |
add_to_cart | User adds a product to cart |
remove_from_cart | User removes a product from cart |
view_cart | User views the cart |
begin_checkout | User starts checkout |
add_payment_info | User enters payment details |
add_shipping_info | User enters shipping details |
purchase | Order is confirmed |
refund | Order is refunded |
You do not have to implement all of them at once. Start with view_item, add_to_cart, begin_checkout, and purchase - these cover the core funnel.
The Items Array
The most important concept in GA4 ecommerce tracking is the items array.
Almost every ecommerce event requires an items array - a structured list of products involved in the event. Each item object contains product details.
Item Object Structure
{
item_id: "SKU-001", // required - unique product identifier
item_name: "Blue Running Shoe", // required - product name
affiliation: "Online Store",
coupon: "SAVE10",
discount: 10.00,
index: 0, // position in a list (for list events)
item_brand: "Nike",
item_category: "Footwear",
item_category2: "Running",
item_list_id: "search_results",
item_list_name: "Search Results",
item_variant: "Size 10",
location_id: "warehouse_sydney",
price: 89.99, // price per unit
quantity: 1
}
Full Data Layer Examples
view_item (Product Detail Page)
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null }); // clear previous ecommerce data
window.dataLayer.push({
event: "view_item",
ecommerce: {
currency: "USD",
value: 89.99,
items: [
{
item_id: "SKU-001",
item_name: "Blue Running Shoe",
item_brand: "Nike",
item_category: "Footwear",
item_variant: "Size 10",
price: 89.99,
quantity: 1
}
]
}
});
add_to_cart
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: "add_to_cart",
ecommerce: {
currency: "USD",
value: 89.99,
items: [
{
item_id: "SKU-001",
item_name: "Blue Running Shoe",
item_brand: "Nike",
item_category: "Footwear",
item_variant: "Size 10",
price: 89.99,
quantity: 1
}
]
}
});
begin_checkout
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: "begin_checkout",
ecommerce: {
currency: "USD",
value: 179.98,
coupon: "SAVE10",
items: [
{
item_id: "SKU-001",
item_name: "Blue Running Shoe",
item_brand: "Nike",
item_category: "Footwear",
item_variant: "Size 10",
price: 89.99,
quantity: 2
}
]
}
});
purchase (Most Critical)
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "ORD-20260314-001", // unique order ID
value: 161.98, // revenue after discounts, before tax/shipping
tax: 14.40,
shipping: 9.99,
currency: "USD",
coupon: "SAVE10",
items: [
{
item_id: "SKU-001",
item_name: "Blue Running Shoe",
item_brand: "Nike",
item_category: "Footwear",
item_variant: "Size 10",
price: 80.99, // price after coupon applied per unit
quantity: 2
}
]
}
});
The Ecommerce Clear: Why It Matters
Every data layer push for an ecommerce event should be preceded by:
window.dataLayer.push({ ecommerce: null });
This clears any previous ecommerce object from the data layer before pushing a new one.
Without this, GTM may read a stale ecommerce object from a previous event - causing wrong product data to be sent on subsequent events.
Always clear before pushing. No exceptions.
GTM Setup for Ecommerce Events
Once the data layer is in place, configure GTM to send these events to GA4.
Create a GA4 Event Tag for Each Event
- GTM → Tags → New
- Tag type: Google Analytics: GA4 Event
- Configuration Tag: your Google Tag (base configuration)
- Event name:
{{Event}}(this reads the event name dynamically from the data layer) - Enable Send Ecommerce data → Source: Data Layer
- Trigger: Custom Event - Event Name matches regex:
view_item|add_to_cart|begin_checkout|purchase
Using a single tag with a regex trigger is more efficient than creating separate tags for each event.
Create a Data Layer Variable
You may need Data Layer Variables to reference ecommerce parameters in other tags (e.g. for Google Ads dynamic remarketing):
- Variable name:
DLV - ecommerce.value - Data Layer Variable name:
ecommerce.value - Data Layer Version: Version 2
Validating Ecommerce Data in GA4
Using GTM Preview Mode
- Trigger an ecommerce action on the site
- In Tag Assistant, confirm the event fires
- Check the Variables tab - confirm
ecommerce.items,ecommerce.value,ecommerce.transaction_idare populated correctly
Using GA4 DebugView
- Enable GA4 Debug mode (add
?debug_mode=1to your URL or use the Google Analytics Debugger Chrome extension) - GA4 → Admin → DebugView
- Trigger ecommerce events - they appear in real time with all parameters
Checking the Ecommerce Report
After 24 - 48 hours:
- GA4 → Reports → Monetisation → Ecommerce Purchases
- Confirm item names, IDs, and revenue are appearing correctly
Common Ecommerce Tracking Errors
Duplicate transactions: The purchase event fires more than once for the same order. Cause: the confirmation page is refreshable, or the tag fires on multiple triggers. Fix: deduplicate using transaction_id in the tag or use a session-scoped check.
Items array is empty or undefined: The data layer push is happening before the product data is available. Fix: push the data layer event after the page/component has fully loaded the product data.
Revenue discrepancy: GA4 revenue does not match actual revenue. Causes: wrong value calculation (including tax/shipping incorrectly), multiple purchase events firing, or refunds not tracked. Fix: audit the value formula and confirm what is being passed.
Missing item parameters: Item name or ID is blank. Cause: the product data is not structured correctly when building the items array. Fix: log window.dataLayer in the browser console after the event fires and inspect the items array.
Final Thoughts
Ecommerce tracking is the most technically demanding part of GA4 implementation - but it is also the most valuable.
When the data layer is correct, you get reliable revenue tracking, funnel analysis, product-level insights, and the ability to build precise audiences from product behaviour.
Get the items array right. Clear the ecommerce object before every push. Validate in DebugView before going live.
In the next article of this series, we will cover:
GA4 and Consent Mode v2 - how to keep tracking without killing data quality.
Related Posts
Data Layer Values Lost Between Pages - How to Persist Variables Across Navigation Without a Developer
9 min read
GA4 and Consent Mode v2 - How to Keep Tracking Without Killing Data Quality
9 min read
GA4 Conversions vs Key Events - How to Set Them Up and What to Actually Track
8 min read
Need Help With Your Google Ads?
I help e-commerce brands scale profitably with data-driven PPC strategies.
Get In Touch