Toggle theme
Jovan ZatezaloGo-to-Market Engineer
Growth

Fix your Shopify ad tracking before you scale: 3.9x tracked ROAS at Passionista

Passionista scaled Meta ads only after every order could be traced back to an ad. Here's the tracking setup, what the honest numbers showed, and the fix that didn't work.

Jovan ZatezaloNovember 9, 20267 min read

Passionista is a Shopify lingerie brand selling in Serbia, Bosnia and Croatia. I do its marketing and engineering. Before we scaled Meta ads, I fixed the Shopify ad tracking so every order could be traced back to the ad that brought it. Then we scaled on that. Result: 3.9x return on tracked ad spend, revenue up 255% against the prior period, conversion rate up 41% to 1.23%.

The tracking itself isn't clever. The point is the order: instrument first, optimize second. Here's what we set up, what the honest numbers showed, and the fix that didn't work.

What was broken

Three markets, ads running daily, and no reliable link between an ad click and an order.

Meta Ads Manager said one thing. Shopify said another. GA4 said a third. Every scaling decision was a guess dressed up as a dashboard.

And the error ran in the flattering direction. Meta claimed more purchases than Shopify had orders. Platforms count with their own attribution windows, view-through included, and every platform takes credit for the same order. Ads looked better than they were, which is exactly when you raise budgets you shouldn't.

That's the normal state of most small Shopify stores I look at. Tracking was "set up once", then the theme changed, an app got installed, iOS updates happened, and nobody checked again.

The Shopify ad tracking setup

Nothing exotic. Four pieces, each one checked against real orders.

1. Google Tag Manager as the one place tags live. No hardcoded snippets spread across the theme. If a tag fires, it's in GTM, and I can see it.

2. GA4 with ecommerce events. view_item, add_to_cart, begin_checkout, purchase, with the order value. The purchase value in GA4 has to match the Shopify order. If it doesn't, nothing downstream means anything.

3. Meta Pixel plus the Conversions API. The pixel alone misses a lot on mobile, and 97.7% of Passionista's sessions are on a phone. CAPI sends the purchase server side, so Meta sees orders the browser never reported.

4. UTMs on every ad. Set once at the account level with Meta's URL parameters, so no ad goes out untagged:

utm_source=facebook&utm_medium=paid&utm_campaign={{campaign.name}}&utm_content={{ad.name}}

The utm_content part matters most. It's what lets you answer "which ad sent this session" in Shopify analytics, months later, without opening Ads Manager.

Judge ads on tracked revenue, not platform ROAS

With tracking in place, the rule got simple: an ad is judged on tracked purchase value against its spend. Target is 3x or better. Under that, it gets cut or reworked.

Every week there's a review: ROAS per ad, profit after product cost, shipping and ads, conversion, and which ads to pause. Platform numbers are an input, not the verdict.

This is where the 3.9x comes from. Not from finding a magic audience. From cutting what didn't pay and moving budget to what did, week after week, on numbers we trusted.

What the honest numbers showed

Once the data was clean, it started saying uncomfortable things.

Paid traffic converted at a third of organic. Over 30 days, paid Meta sessions converted at 0.75%. Organic Instagram and Facebook traffic converted at 2.3%. Same store, same products. Paid buys volume, not buyers. Before raising the budget, check where the paid clicks land.

1 in 7 paid clicks landed on a page with no products. About 14% of paid Meta sessions hit the bare /products page, a "Collections" list with nothing to buy. The traffic came from one carousel ad, confirmed by utm_content. Without UTMs on every ad, this would have looked like "Meta traffic is bad" and nobody would have found the ad.

Speed wasn't the problem. Product page LCP at p75 was 1.09s. Everyone checks page speed first. Ours was fine. The problems were on the page, not under it.

The fix that didn't work

The carousel ad's Website URL pointed at the right collection. In Ads Manager, under Personalised destinations, "Product browsing" was on. That looked like the cause, so I turned it off.

A few days later I checked. Share of the ad's sessions landing on /products: 72% before, 73% after. Nothing changed. The absolute numbers had dropped, but only because spend went down around the same time. If I'd looked at raw sessions instead of the share, I'd have called it fixed.

Turned out the catalog was the mess: not synced with Shopify, every item marked in stock, around 14 product URLs returning 404. The setting I could see wasn't the one doing it.

What we did instead:

  • A stopgap redirect from /products to the main collection, keeping UTMs and fbclid, so the clicks at least land on products.
  • The real fix: rebuild the Meta catalog as a Shopify sync.

Lesson: every fix gets a check date and a number to compare against. Write down what should change, then look.

Then fix the store, and measure that too

Tracking also showed where the store leaked. On mobile, Add to cart sat 1.7 screens below the top. No shipping or returns info near the button. No size guidance at the picker.

We shipped, in one day:

  • A trust block under the button: cash on delivery or card, same day shipping, free shipping threshold with "how much is left", 14 day returns.
  • Size guidance next to the size picker, linked to the size chart.
  • A sticky Add to cart bar on mobile.

Eight days later, against the eight days before: add to cart rate went from 2.19% to 2.70%, conversion from 0.81% to 1.01%.

And the next leak showed up right away. Cart to checkout on mobile was about 50%, against about 90% on desktop. The slide cart greys out the checkout button until a terms box is ticked, and on a phone that reads as broken. That's next.

This is the loop. It never ends, and that's fine. Tracking is what makes each step a decision instead of a guess.

What I'd do differently

Start the weekly review before scaling, not after. The tracking was right long before the routine was. A fixed time every week to look at ROAS per ad, profit and conversion is what turns clean data into decisions. Without it, clean data just sits there.

Give every fix a check date and a number from day one. The Product browsing miss only got caught because there was a check on the calendar. Write down the ratio you expect to move and the date you'll look.

Check your own tracking this week

Five minutes, no tools needed:

  1. Does GA4 purchase revenue match your Shopify revenue for last week, within a few percent?
  2. Is Meta CAPI sending purchase events, not just the pixel? Check Events Manager.
  3. Do UTMs survive checkout? Place a test order from a tagged link and look for it in Shopify.
  4. Any duplicate purchase events? One order, one event.
  5. When did someone last look at any of this?

If two or more fail, don't raise the ad budget yet. Fix tracking first.

If you want a second pair of eyes, I do a free 30 minute GTM Teardown: your tracking, your funnel, where revenue leaks. Book it on zatezalo.dev.

$ I build in public. Follow along on X @zax_eng

Ready to Optimize Your Store?

Want this applied to your funnel? I'll show you where the revenue is leaking.