Skip to content

Analytics

A data layer specification for ecommerce stores

A written data layer spec keeps GA4, Google Ads, Meta and your developers on the same event names, item fields and value rules. The template, field by field.

By CartKernel · Published

A data layer specification is one document that says, for every event on the store, what triggers it, what it is called, and what it carries. Without one, GA4, Google Ads, Meta and the developers each decide for themselves, and the disagreements surface later as revenue that does not match, conversions that do not fire, and a return on ad spend that means something different in every report. This is the structure of the spec we write for stores, with the decisions inside it explained.

What the document contains

  1. Conventions: names, currency, the value definition, privacy rules.
  2. A page context object present on every page.
  3. The event table: trigger, name, parameters.
  4. The item object, defined once and reused.
  5. Platform notes: how it is implemented on Shopify, WooCommerce or a headless front end.
  6. A test matrix and a version log.

Six sections, usually eight to twelve pages. It lives in the repository next to the theme, and every theme or checkout change is reviewed against it.

Conventions

Use GA4’s recommended event names. view_item, add_to_cart, purchase and the rest exist so the platform’s reports and Google Ads conversion imports understand the events without mapping. Invent a name only where no recommended event fits, and write it in snake_case. The recommended events reference lists the parameters each one expects.

Currency on every event that carries a value. An ISO code, taken from the checkout currency, not the store default. Stores selling in several presentment currencies get this wrong most often.

Decide what value means and never vary it. Our default for purchase is the order subtotal after discounts, before tax and shipping, with tax and shipping sent as their own parameters. The reason is comparability: Google Ads and Meta receive the same value, so return on ad spend means the same thing in both, and the number can be checked against the Shopify export column of the same name. A store can choose a different definition, but it must be one definition, written in the spec.

Clear the ecommerce object between pushes. On tag manager implementations, push { ecommerce: null } before each ecommerce event so item arrays from the previous event do not merge into the next. Google’s data layer documentation explains why.

No personal data in the clear. Email and phone for enhanced conversions are either hashed before they reach the data layer or handed to the tag that hashes them, and only when the consent state allows it. The enhanced conversions entry describes what Google accepts, and how to set up enhanced conversions for Shopify covers the platform specifics.

The page context object

Pushed once per page before any tag fires, so every tag can read it.

Key Values Used for
page_type home, collection, product, cart, checkout, search, account, blog, other Template-level reporting and trigger conditions
currency ISO code of the active checkout currency Value handling
market Country or market code Regional reports and consent defaults
language Language code Localised reporting
customer_status guest, new, returning New versus returning revenue
customer_id Hashed identifier when logged in User-ID reporting
cart_value, cart_item_count Numbers Remarketing audiences
consent analytics and ads booleans, when the consent platform exposes them Debugging Consent Mode

customer_status needs a rule: a customer is “returning” when the order count on the account is above zero at the time the page loads. That rule feeds how you track new versus returning customer revenue, so write it down.

The event table

Event Fires when Required parameters Items
view_item_list A collection, search results or recommendation block renders item_list_id, item_list_name Visible products with index
select_item A product card is clicked item_list_id, item_list_name The one product
view_item A product page loads currency, value The product with selected variant
add_to_cart The add button succeeds currency, value Added item and quantity
remove_from_cart Quantity reduced or line removed currency, value Removed item and quantity
view_cart Cart page or drawer opens currency, value Every line
begin_checkout Checkout page loads currency, value, coupon Every line
add_shipping_info Shipping method chosen shipping_tier Every line
add_payment_info Payment method chosen payment_type Every line
purchase The order is confirmed transaction_id, currency, value, tax, shipping, coupon Every line
refund A refund is issued, sent server-side transaction_id, value Refunded lines
search Site search submitted search_term none
sign_up, login Account created or session started method none
generate_lead Newsletter or SMS signup lead_source none

One row per event, with the trigger described in terms a developer can implement and a tester can reproduce. “The add button succeeds” means after the cart API returns, not on click.

The item object

Defined once, reused in every items array.

  • item_id: the identifier your Merchant Center feed uses as its offer ID, so Shopping reports and analytics agree on what sold. Put the SKU in a separate item_sku parameter if you need it.
  • item_name: the product title without the variant.
  • item_variant: the variant title, for example “Large / Navy”.
  • item_brand: the vendor field.
  • item_category through item_category5: the collection or category path, from the primary category.
  • price: the unit price after line-level discounts, in the event currency.
  • quantity: the line quantity.
  • discount: the per-unit discount applied, when any.
  • index, item_list_id, item_list_name: where the item was seen, carried through to purchase when available.

Rule: the sum of price times quantity across the items must equal the event value, given the value definition above. When they differ, item revenue and event revenue in GA4 disagree and nobody can say which is right.

A purchase push under these rules looks like this:

{
  "event": "purchase",
  "ecommerce": {
    "transaction_id": "1042",
    "currency": "CAD",
    "value": 148.00,
    "tax": 19.24,
    "shipping": 12.00,
    "coupon": "WELCOME",
    "items": [
      {
        "item_id": "shopify_CA_812_3301",
        "item_name": "Trail Jacket",
        "item_variant": "Large / Navy",
        "item_brand": "Northline",
        "item_category": "Outerwear",
        "item_category2": "Jackets",
        "price": 148.00,
        "quantity": 1
      }
    ]
  }
}

The values are illustrative; the shape is the point.

Platform notes

Shopify. The checkout cannot run theme code, so checkout events come from the Web Pixels API. A custom pixel subscribes to the standard events, checkout_started, checkout_completed and the others, and forwards them in the GA4 shape above. The cleanest implementation runs the whole funnel through the pixel, including product and collection views, so nothing is counted once by the theme and again by the pixel. If the Google and YouTube channel app is also connected, decide which path sends GA4 events and switch off the other. The standard events and their payloads are documented in the Web Pixels API reference.

WooCommerce. A tag manager plugin or a small custom plugin pushes the data layer on each template, with checkout events hooked into the checkout block and the purchase on the order-received page guarded against refresh with a flag stored per order.

Headless. The front end owns the client pushes; the server sends purchase and refund through the Measurement Protocol using the same transaction_id, so GA4 deduplicates the pair. The spec marks each event as client, server or both.

Whichever platform, the spec names the dedupe key and the owner of each event. Server-side tagging describes the routing once collection moves off the browser, and does an ecommerce store need server-side tagging helps decide whether it should.

The test matrix

Run before every release that touches the theme, checkout or tags, with GA4 DebugView and the tag manager preview open.

  • One product from each template variation, with a variant selected and without.
  • Add, change quantity, remove, from the product page and from the cart drawer.
  • A discount code, a free-shipping order, a multi-currency order.
  • Guest checkout and logged-in checkout.
  • Refresh and back button on the thank-you page: exactly one purchase.
  • Compare one day’s purchase events with Shopify’s order count, which is the short form of the reconciliation we run monthly.

When the purchase row fails, Google Ads conversion tracking not working and GA4 purchase event not firing cover the common causes.

Versioning and ownership

Give the spec a version number and a changelog. Every pull request that touches tracking references the version it implements. Name one owner, usually whoever owns analytics, and one developer who reviews tracking changes. The data layer entry is the short definition for stakeholders who need the concept without the document; the GA4 ecommerce tracking and ecommerce development services are where we write and implement it for stores.


Sources

Find the leak.

A free Growth Analysis ranks what your store should fix first, by revenue at stake.