Why GA4 is blind to Claude shoppers — and what we built instead
When Claude or ChatGPT browses your store on a customer's behalf, GA4 sees a session with no referrer and dumps it into 'direct.' Here's what's actually happening, and why we stopped trying to retrofit the existing analytics stack to fix it.
I had the conversation three times in the same week with three different e-commerce Product Directors:
"We tried to find AI agent traffic in GA4. There's nothing there. Either the agents aren't visiting, or our reporting is broken."
The reporting isn't broken. The agents are visiting. GA4 just can't see them — by design, not by bug.
This post is the long version of why, written for Product and Engineering Leads who already feel the gap and want a clean explanation they can forward to their CMO.
What GA4 actually measures
GA4 is a referrer-and-cookie analytics product. It learns about a session from three signals:
- The
RefererHTTP header on the first request (where did the user come from?) - The UTM parameters in the URL (which campaign?)
- A first-party cookie (
_ga) that ties subsequent pageviews to the same session
When all three are present, GA4 can attribute the visit. When they're not, the session lands in the "direct / none" bucket — the catch-all for traffic GA4 couldn't classify.
What an AI agent session looks like over the wire
When a Claude Desktop user types "buy AA batteries on yourstore.ch", this is roughly what happens at the network layer:
- Claude's browser MCP spins up a headless Chromium instance
- The instance navigates directly to
https://yourstore.ch— no link click, no referring page - The HTTP request has no
Refererheader (or a meaningless one —chrome-extension://...) - There are no UTM params (the agent didn't click a campaign link)
- The browser is fresh — no
_gacookie from a prior session
GA4 sees a session that:
- has no referrer
- has no campaign tag
- has no returning-user signal
It does the only thing it can do: it logs it as direct / none, which most teams treat as "someone typed our URL into their address bar." Which, if you squint, is technically true — except the someone is a robot acting on behalf of a human, and you have no idea this happened.
Why this isn't fixable inside GA4
The instinct, when teams figure out the gap, is to try to detect the agent on the client and fire a custom event:
if (navigator.webdriver) {
gtag('event', 'agent_session', { platform: 'unknown' })
}
This is a dead end for three reasons:
1. navigator.webdriver is unreliable. Stealth automation libraries (playwright-extra, puppeteer-extra-plugin-stealth) patch this to false by default. Real Claude Desktop with the bundled MCP server doesn't have stealth on, but Operator and ChatGPT Agent's hosted browsers do. You'd catch some traffic and miss most of it.
2. GA4's data model isn't built for it. Even if you fire the event, the session is still a "direct" session in GA4's funnels, segments, and exploration reports. You'd be adding a custom dimension that nobody's existing dashboards reference, that doesn't roll up into Conversions, and that requires every analyst on your team to know to filter on it.
3. The interesting question isn't "did an agent visit." It's "did the agent succeed." GA4 measures pageviews, not task completion. An agent session that loaded your homepage, visited 3 product pages, opened a variant selector, failed to operate it, and gave up looks identical to GA4 to a human bouncing — same path, same exit, same nothing.
The bottom of the funnel is where agents fail. GA4's instrumentation is at the top.
The shape of the problem we kept hitting
When we tried to make agent traffic visible inside the existing CRO stack — Hotjar, Contentsquare, FullStory — we hit a related wall. Those tools record human sessions. They have entire feature sets dedicated to deduplicating bot traffic out of the data, because a 95% bounce rate on bot sessions would destroy the CRO numbers a CMO is paid on. They're not going to let you in on the bot side.
So the question reframes:
- GA4 won't show you which sessions are agent-driven (referrer model is wrong)
- CRO tools won't show you what agents do on those sessions (behavioural model is wrong)
- Bot management tools will block the agents (security model is wrong)
What's left is to build the thing that's missing: a passive snippet that recognises agent-driven sessions on commerce sites, and an active replay that runs a real Claude agent against your store and captures where it fails.
Which is what Serge does.
What the Serge snippet actually captures
When a session lands on a site running serge.js, the snippet runs a tiered detection model in the browser:
- Tier 1 (deterministic) — known agent UA strings,
navigator.webdriver(when present), Claude DOM artifacts, known-extension Web Accessible Resources - Tier 2 (heuristic) — Sec-Ch-Ua-Platform mismatch, CDP runtime leaks, worker-context tampering signals
- Tier 3 (behavioural) — 5-second observation window for mouse entropy, scroll velocity, hover/click sequencing
Sessions classified as agent-driven are reported. Human sessions are dropped client-side — we never see them. This isn't an analytics tool with an agent filter; it's an agent-only tool by construction.
What the active replay does
The snippet is the monitor. The active replay is the diagnostic. When a Product Director asks "why did 47 ChatGPT sessions fail at the variant selector," the replay runs Claude Desktop (via MCP) against the same product page, captures every step (DOM event, accessibility tree snapshot, agent reasoning, screenshot), and renders it as a timeline you can scroll through.
The replay is what closes the loop GA4 can't close. GA4 tells you traffic arrived. The replay tells you what the traffic tried to do, and what your site refused to let it do.
Why we stopped trying to retrofit the existing stack
There's a genre of analytics product that pitches itself as "GA4 for X" — GA4 for mobile, GA4 for B2B, GA4 for product-led growth. We considered that framing for about two weeks. We dropped it because the layer GA4 operates at — referrer-and-cookie session analytics for human behaviour — isn't where the agent-commerce problem lives.
The agent-commerce problem lives one layer down: at the DOM, at the accessibility tree, at the variant selector that's a <div onClick> instead of a <button>. That layer doesn't have an analytics product yet because, until 2026, nobody was navigating sites at that layer except screen-reader users — and accessibility auditing is a different commercial category, framed around legal compliance rather than commercial outcomes.
What Serge measures is the same surface accessibility tools have always measured, but framed around can the agent complete the task it was sent to do. Which turns out to be a much more interesting question than does the site comply with WCAG 2.1 AA, because the answer affects revenue this quarter rather than legal risk next year.
What to do with this if you're a Product Director
Three things, in order:
- Run the scanner on your domain. Free, 30 seconds, no signup. It's the cheapest possible read of how badly an agent would struggle on your site.
- Forward the result internally. The scanner output is designed to be screenshotted and dropped into Slack. The conversation it starts inside your team is the most valuable part — not the score.
- If the score is bad, install the snippet. You'll see how much agent traffic is actually hitting you (almost always more than the team expects) and where it's getting stuck. From there, the active replay diagnoses the specific failures, and you ship fixes against real evidence rather than guesswork.
If GA4 was going to surface this, it would have done so by now. The tooling has to live somewhere else.
— Yann
Run the scanner on your store
Free, deterministic, 30 seconds. See exactly which agent failures apply to your domain.
Scan your domain