Single /cart/add.js request firing AddToCart 3 times on Meta pixel — welcome kit flow

Hey everyone,

We have a store with a custom purchase flow — no PDP, everything on the homepage. When the customer clicks the CTA, we call /cart/add.js with multiple items in a single request (1 main product + 2 free gift items with custom properties), then redirect straight to /checkout.

The problem: Meta is receiving 3x AddToCart events — one per item in the batch, including the free gifts. We only want 1 ATC firing for the main paid product.

What we tried:

  1. Gift suppression via line item properties in the pixel — didn’t work because product_added_to_cart never fires at all with a multi-item /cart/add.js call (confirmed Shopify bug: ref)

  2. document.dispatchEvent custom event from theme JS after cart add — pixel sandbox iframe can’t hear main window DOM events

  3. Currently testing window.Shopify.analytics.publish from theme JS + analytics.subscribe in the pixel to manually fire 1 clean ATC for the paid product only

Questions:

  1. Is window.Shopify.analytics.publish the right approach here?

  2. Has anyone solved the 3x ATC problem in a similar welcome kit / bundle direct-to-checkout flow?

  3. Any better alternatives we’re missing?

Thanks!

Hey @Yosh_Casillas, thanks for reaching out. Happy to help clarify here.

What’s happening is that WPM fires one product_added_to_cart standard event per line item in the /cart/add.js response by design, and since Meta’s app pixel subscribes to that standard event, it picks up all three and translates each one into its own AddToCart. There’s currently no built-in way on the platform side to suppress product_added_to_cart for specific line items, so the 3x behavior is unfortunately expected right now.

That said, on your window.Shopify.analytics.publish approach, I’d say that’s definitely workable since it’s technically the officially supported bridge between theme JS and the pixel sandbox, so publishing a custom event after your /cart/add.js resolves and subscribing to it in a custom pixel to fire one clean AddToCart for the paid product only is a solid workaround for the client-side signal.

The main thing to watch out for is that if you’re also running the native Meta sales channel app pixel alongside your custom pixel, it’ll still fire its own events from product_added_to_cart independently, so you’d want to make sure you’re not doubling up there as the native Meta Pixels can’t pass the event over.

Hope that helps clarify things! Happy to dig in further if needed.