Fully Indexed, Zero Organic Clicks: Reading Search Console and GA4 Together
Google Search Console says stackbilder.com is fully indexed. It also says the site earned zero organic clicks in the last 90 days. GA4 says sessions grew 65% week over week. All three facts are true at the same time, and if you read any one of them alone, you will do the wrong thing next.
Read the first one alone and you relax — indexing is done, SEO is "handled." Read the second alone and you panic-publish a content calendar. Read the third alone and you conclude everything is working. We ran our first fused Search Console + GA4 positioning analysis last week, and the single most valuable output wasn't a keyword opportunity. It was finding out that our top product page had been split in half by a trailing slash.
Search Console and GA4 answer different halves of one question
Pre-click and post-click data are two halves of one funnel, and most teams read them in separate tabs on different days.
Google Search Console knows everything that happens before the click: which queries your site appears for, how many impressions each earns, where you rank, and — via the URL Inspection API — whether each URL is actually in the index. It knows nothing about what visitors do.
GA4 knows everything that happens after arrival: which pages pull sessions, where traffic comes from, who bounces and who stays. It knows nothing about the demand you're invisible to.
Neither dataset can answer "is our positioning working?" on its own. So we stopped asking them separately. Our agent pulls both into one bundle — GSC query and page data over 28- and 90-day windows plus per-URL index coverage, fused with the GA4 snapshot of pages, sources, and engagement — and reads them against a fixed sequence of checks:
- Traffic mix → growth mode. Sum the GA4 sources. Mostly direct, referral, and social? You're distribution-driven, and GA4 behavior is your scoreboard right now. Mostly organic? You're search-driven, and GSC leads.
- Gravity center and leaks. Rank pages by sessions. Where traffic clusters is what your audience actually wants — regardless of what you built the site around. Read bounce per page: high bounce on a high-traffic page is a top-of-funnel leak; low bounce on login, settings, or pricing is retention signal at the bottom.
- Resonance mismatch. Do the pages you built for SEO appear in either dataset? If a landing cluster pulls zero impressions and zero engaged sessions, those pages are speculative bets, not current wins. Say so plainly.
- GSC mode switch. If impressions are near zero, organic is dormant and Search Console's job is to be a tripwire, not a dashboard. If impressions exist, run the query-level checks.
- Rank actions by leverage, split into "this week" and "watch."
The ordering matters. Growth mode frames every other read: a distribution-driven site judged by its Search Console numbers looks like a failure when it's actually just young.
What the fused read found: our SEO pages weren't the story
The honest findings, in descending order of usefulness:
The site is distribution-driven. Direct, referral, and social dominated the source mix, up 65% week over week. Organic was a rounding error. That one classification reframed everything: our positioning is currently judged by what visitors do after arriving from a link someone shared — not by rankings.
The SEO landing cluster earned zero, twice. The comparison and content pages we built specifically for search pulled approximately zero GSC impressions and approximately zero engaged GA4 sessions. Not "underperforming" — absent from both halves of the funnel. We've failed in public before and the lesson repeats: pages built for an audience that hasn't arrived yet are bets, and bets should be labeled as bets in your own reporting.
The real gravity center is the product. img-forge, our headless image generation API, is where sessions actually cluster. The audience votes with traffic, and it voted for the tool, not the essays about the tool.
And the top product page was split in half. This is the finding that paid for the whole exercise:
| URL | Sessions (7d) | Bounce |
|---|---|---|
/img-forge |
44 | 50% |
/img-forge/ |
7 | 71% |
Same page. Two URLs. Both returned HTTP 200 with identical content, so GA4 dutifully recorded them as separate pages. Every per-page metric on our most-visited product page — sessions, bounce, conversion — was fragmented and understated, and the bounce rates weren't even comparable because the populations differed.
Canonical tags protect your rankings, not your analytics
Here's the part worth quoting: canonical tags deduplicate your search results; they do nothing to deduplicate your analytics.
Both URL variants correctly emitted <link rel="canonical" href="https://stackbilder.com/img-forge">, so Google consolidated the duplicates and rankings were never at risk. That's exactly why this class of bug survives: the SEO layer silently absorbs the damage, nothing looks broken, and the measurement layer quietly lies to you for months.
The root cause was mundane. The site runs on Astro with server output on Cloudflare Workers, and with no explicit trailing-slash policy, the router resolved both forms. The fix is a normalizer at the top of the Astro middleware, before anything else runs:
if (
context.url.pathname.length > 1 &&
context.url.pathname.endsWith("/") &&
(context.request.method === "GET" || context.request.method === "HEAD")
) {
const normalized = context.url.pathname.replace(/\/+$/, "") || "/";
return context.redirect(normalized + context.url.search, 301);
}
Two details in there earn their keep. It preserves the query string, because /pricing/?plan=pro must land on /pricing?plan=pro, not /pricing. And it only touches GET and HEAD, because a 301 downgrades a POST to a GET in every mainstream client — normalize your API routes with the same enthusiasm and you'll convert form submissions into page views.
Merged isn't live, so we verified against production, not the diff:
GET /img-forge/ -> 301 -> /img-forge (200)
GET /pricing/?a=b -> 301 -> /pricing?a=b
GET / -> 200 (untouched)
POST /api/csp-report/ -> 204 (untouched)
From that deploy forward, the product page is one page again. The historical data stays split — analytics hygiene compounds, which is the strongest argument for doing it before you need the funnel analysis rather than after.
Zero organic clicks is a watch state, not a crisis
The counterintuitive output of the fused analysis was a decision to not act on SEO this week.
A fully indexed site with zero organic clicks is the normal state for a young domain, not a failure. Domain authority accrues slowly; index coverage just means you're eligible to compete, not that you've competed. We went live recently, and the fused read said our energy belongs in the channel that's actually growing — distribution — while Search Console runs as a tripwire with one trigger condition: the first sustained impressions.
The failure mode to avoid in that state is manufacturing insight from no data. A query report with single-digit impressions cannot tell you anything; torturing it into a "keyword strategy" produces confident nonsense. When impressions do arrive, there are exactly four checks worth running: high impressions with near-zero clicks (rewrite the title and meta), improved position with falling CTR (the SERP feature above you changed), one query ranking on multiple pages (cannibalization), and queries ranking with no dedicated page (a real content gap). Until then, the discipline is to watch.
One more thing the exercise clarified: this is also what GEO — getting cited by AI systems, not just ranked by search engines — actually demands. Generative engines don't reward keyword volume; they reward pages that own a specific question and anchor their claims in verifiable artifacts — real numbers, real output, real code. That's the same bar the fused analysis holds our pages to, and it's the same reason we invest in machine-readable discovery surfaces for agents. The era where pre-click means "a human typed a query" is already ending; the funnel discipline transfers.
The method, compressed: fuse pre-click and post-click into one read. Let the traffic mix tell you which half is your scoreboard. Find the gravity center and believe it over your own roadmap. Label speculative pages as bets. Fix measurement before strategy — you can't reposition what you can't count. And when one half of the funnel is empty, set a tripwire and go work on the half that's moving.
Built with Stackbilder on Cloudflare Workers. The image API that turned out to be our gravity center: img-forge. More field notes at blog.stackbilt.dev.