The Complete WooCommerce Google Tag Manager dataLayer Guide (GA4, 2026)

July 7, 2026

Google Tag Manager is the right way to run analytics on a WooCommerce store — if the dataLayer feeding it is complete and correct. This guide is the reference we wish existed: the full event map, the payload rules that GA4 actually enforces, container wiring, and the classic mistakes that silently corrupt data for months.

Why GTM instead of pasting gtag.js

With GTM, your site publishes facts (a clean dataLayer: “someone added product X for €29”) and the container decides which platforms consume them — GA4 today; Google Ads, Meta or a heatmap tool tomorrow, without touching the site. Marketing iterates in GTM’s interface; the site’s code stays stable. The dataLayer is the contract between the two worlds, which is why its quality decides everything downstream.

The full WooCommerce event map

GA4’s eCommerce schema maps onto WooCommerce like this — the funnel in bold:

Payload rules GA4 actually enforces

GA4 drops or mangles events that break these rules — silently:

  1. Always reset before pushing: dataLayer.push({ ecommerce: null }) before every ecommerce push, or items from the previous event bleed into the next (the single most common corruption).
  2. value is a number, currency is mandatory. “€29.99” as a string breaks revenue; a missing currency breaks it quietly in multi-currency stores.
  3. Every item needs item_id and item_name. Decide once whether item_id is the product ID or SKU and never mix — mixing splits one product into two GA4 entities.
  4. Categories: item_category through item_category5, most general first. Deeper taxonomy is discarded.
  5. transaction_id on purchase — GA4 dedups on it; it is also your reconciliation key against WooCommerce order numbers and the bridge to any server-side events.

Container wiring (the 20-minute version)

  1. One GA4 configuration tag (your G- ID), firing on Initialization — after the consent default (below).
  2. One GA4 event tag per event, trigger = Custom Event matching the event name, with “Send Ecommerce data → Data Layer” enabled — or a single event tag using the event-name variable if you prefer a compact container.
  3. Built-in variables: enable the ecommerce ones; add a Data Layer Variable for anything custom you push.
  4. Test in Preview mode against a real order (use a 100% coupon on a staging product) before publishing. The published version — not the draft — is what runs for customers.

Or import a prebuilt container: TrackPilot ships one where every tag, trigger and variable above is already wired to its dataLayer.

Consent Mode v2 changes the firing rules

For EEA traffic your tags must respect the four consent signals, with defaults denied printed before the container loads. The dataLayer keeps recording either way — consent gates what the tags do with it. Full walkthrough: Consent Mode v2 for WooCommerce.

Purchases: one order, one event — ever

Thank-you pages get refreshed, bookmarked and revisited from order emails. Deduplicate per order (order meta server-side; GA4’s transaction_id as the backstop) and your revenue survives all of it. If you add server-side events later (why you should), the same transaction ID is what keeps browser + server from double-counting.

The five silent data-corrupters

  1. No ecommerce: null reset (item bleed)
  2. Duplicate GA4 config — a theme’s hardcoded gtag plus your container (every event doubles)
  3. item_id flip-flopping between SKU and product ID after a plugin change
  4. Tax-inclusive prices in events, tax-exclusive in GA4 settings (or vice versa)
  5. Testing only as a logged-in, consent-granted admin

Audit each one quarterly; any of them can run unnoticed for a year.

TrackPilot ships all of this out of the box — every GA4 eCommerce event for WooCommerce (classic and Blocks), Consent Mode v2, an importable GTM container and a live debugger. See TrackPilot →

Liked this? The plugins do the heavy lifting.

Browse the plugins