Dev.to WebDev 🛠 Dev 👁 0 📖 2 min read

The pre-deploy tag check that stopped us shipping broken purchase events

At ramo.co.il we run a Next.js storefront on Vercel with GA4, Google Ads, Meta and TikTok pixels on the same checkout path. A purchase that fires twice, fires late, or never fires at all looks fine in the UI and wrong in

At ramo.co.il we run a Next.js storefront on Vercel with GA4, Google Ads, Meta and TikTok pixels on the same checkout path. A purchase that fires twice, fires late, or never fires at all looks fine in the UI and wrong in every dashboard. We stopped treating that as a "check later" problem.

What kept going wrong

The bugs were boring and expensive:

  • A layout change moved the thank-you page. Purchase fired on the wrong route, or not at all.
  • A consent or script-load race meant Meta saw the event and GA4 did not, or the other way around.
  • A "helpful" retry in a client handler duplicated the same order id across two hits.

None of those show up as a red build. They show up as mismatched spend and messy attribution a week later.

The gate we added

Before we push a branch that touches checkout, tracking, or the thank-you page, a Playwright suite has to pass. It is not a full shop crawl. It walks a happy-path purchase (or a mocked one) and asserts, for each vendor tag we care about:

  1. It fires — the request or dataLayer push actually happens.
  2. It fires once — no double hit for the same order.
  3. It fires at the right moment — after confirmation, not on cart view or add-to-cart.

We treat GA4/Google Ads, Meta and TikTok the same way. If any of those three fail the check, the branch does not move forward. Bing is out of that gate for now; we would rather ship with a known gap than block everything on a pixel we are not fixing yet.

Why Playwright instead of "look at the network tab"

Manual checks do not survive Friday deploys. Playwright can wait for the network, read dataLayer, and fail the job with a clear screenshot when a tag is missing. The suite lives next to the app so a tracking change and its test land in the same PR.

We also keep pixel IDs in env and keep business rules (fees, thresholds, banners) in the database. Tracking tests should not care which free-shipping threshold marketing picked this week.

What we still watch after deploy

The gate catches regressions on the critical path. It does not replace feed honesty, offline conversion uploads, or reading the live dashboards. Those stay as separate jobs. The point of the tag check is narrower: never again ship a thank-you page that looks perfect and reports nothing.

If your store mixes several ad pixels on one checkout, put the "fires once, at the right time" assertion in CI before you argue about bid strategy. We run that discipline on every change that touches our storefront checkout and analytics path.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.