You launch Meta ads. Clicks are cheap, engagement looks great, conversions are rolling in.Then you open GA4… and see this mess:
1. Half of your purchases have no source
2. facebook / cpc? Nowhere. But (direct) / (none) is having a party
What’s going on?
It’s the infamous in-app browser from Meta. Facebook and Instagram don’t open links in Chrome or Safari — they trap users inside their own little browser. And that’s where the attribution train crashes.
Here’s how it breaks:
1. User clicks the ad → site opens inside Meta’s in-app browser.
2. Referrer is stripped (because it’s an app), fbclid or UTM parameters get lost in redirects or dynamic loads.
3. The user comes back later via Safari or Chrome — either typing the URL manually or from a saved tab. GA4 thinks it’s a brand-new (direct) session.
The result? Meta drives sales. GA4 sees… nothing.
Here’s how I fix this in my own projects:
1. I capture UTMs from landing page URLs and store it in BigQuery. Then I link it with Meta Ads API exports. This is what we call the Matching Loop: click → session → event → export → match.
2. I run GA4 through server-side GTM and pipe everything into BigQuery. That helps bypass ad blockers and keep the context.
3. I stitch sessions manually when needed — using IPs, user-agent, fingerprints. If there’s a login, I connect client_id to user_id and deduplicate the mess.
Bottom line:
Not every “direct” is direct. Sometimes it’s just broken paid social that never got proper credit. If you’re not tracking UTMs, syncing with Meta’s API, and building your own attribution — you’re flying blind.
If you work with GA4 to BigQuery exports, be sure to check out my SQL cheat sheet.