GA4 add_to_cart Not Tracking in WooCommerce? Here’s Why (All 6 Cases)

July 7, 2026

The purchase event gets all the attention, but add_to_cart breaks more often — and more silently. Without it, GA4’s funnel reports are meaningless: you cannot see where shoppers drop off between product and checkout, and Google Ads loses its best remarketing signal. Six cases cover virtually every WooCommerce store where add-to-cart tracking is dead or partial.

1. AJAX add-to-cart buttons never navigate

On shop and archive pages WooCommerce adds products via AJAX — no page load, no gtag page hook, nothing for load-based snippets to catch. If your tracking only fires add_to_cart on the single product page, every archive-page add is invisible.

Fix: listen for WooCommerce’s JavaScript event added_to_cart (fired on document.body after a successful AJAX add) and push the dataLayer event from there, using the product data attached to the button.

2. The single product page posts a normal form

The opposite trap: on single product pages the add-to-cart is a normal form POST, not AJAX. The page reloads, and any listener waiting for added_to_cart never hears it.

Fix: detect the add server-side (WooCommerce’s woocommerce_add_to_cart PHP hook), stash the event in the session, and push it to the dataLayer on the next page render. This survives the reload and also catches adds from redirects and “buy now” links.

3. Variable products report the parent — or nothing

A shopper picks “Blue / XL” and your event either reports the parent product with no variant, or fails because the variation ID is not in the button markup.

Fix: for variable products, read the selected variation_id from the form at submit time, and send GA4’s item_variant alongside item_id. If you deduplicate item IDs by SKU, make sure variations have their own SKUs — a surprisingly common gap in the catalog itself.

4. WooCommerce Blocks use a different event system entirely

The Products block, All Products block and the Blocks cart do not fire the classic hooks or the jQuery added_to_cart event. Stores that migrated to block-based shop pages often lose add-to-cart tracking on exactly those pages while the legacy templates keep working — a partial failure that is easy to miss.

Fix: subscribe to the Store API’s data stores (wp.data) or use the experimental__woocommerce_blocks-cart-add-item event. This is genuinely different plumbing; a snippet built for classic WooCommerce cannot see it.

5. Quantity and price are wrong (so you filter the event out later)

GA4 accepts your event but analysts discard it: quantity hardcoded to 1 regardless of the selector, price missing so “add to cart value” reports zero, or price sent with tax when your GA4 property is configured without (or vice versa).

Fix: read the real quantity from the form; send price per unit and let GA4 multiply; decide the tax basis once, store-wide, and apply it to every event in the funnel consistently.

6. It works — but only for you

The classic self-own: tracking verified while logged in as admin, with a consent banner you accepted months ago and an ad-blocker whitelist for your own site. Real visitors: consent denied by default (event correctly withheld), or blocked entirely.

Fix: test in a fresh private window with the banner untouched, then again after accepting. If you exclude admin traffic (you should), remember your own adds are supposed to be missing — check with a non-admin test account instead.

The pattern behind all six

add_to_cart has to be captured in four different ways (AJAX event, PHP hook + session, variation form read, Blocks data store) depending on where the click happens. That is why hand-rolled snippets degrade with every WooCommerce update — and why this belongs in maintained code, not a theme’s functions.php.

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