DEV Community

Lucas
Lucas

Posted on

"I built 8,000 programmatic SEO pages. Google indexed zero. A GSC postmortem."

Status: this is a live postmortem, not a victory lap. As I write this the site is still at 0 indexed pages. The interesting part isn't the win — it's the diagnosis.

The setup

I run 커피콩 (CoffeeCong), a Korean coffee-rewards app. Alongside it I shipped a programmatic-SEO site: a "workability" map of Seoul cafes — every cafe scored on outlets, Wi‑Fi, seat room, noise, and price, then sliced into ~8,000 server-rendered landing pages:

  • /coffeemap/area/{district} — 25 districts
  • /coffeemap/area/{district}/{purpose} — district × 7 purposes
  • /coffeemap/station/{station} and /station/{station}/{purpose} — ~313 subway stations × purposes
  • /coffeemap/cafe/{id} — ~6,000 individual cafes

All SSR (Express), each page with a unique <h1>, canonical, JSON‑LD, FAQ, and cross-links. Textbook programmatic SEO.

The crash

Search Console told a brutally clean story:

Sitemaps:   8,653 submitted  /  0 indexed
Impressions: 05-24 → 05-29  ramp to 209/day
             05-30           collapse to ~0   ← and it stayed there
Enter fullscreen mode Exit fullscreen mode

URL Inspection on every sample URL came back the same way:

  • Hub + category pages → "Crawled — currently not indexed"
  • Long-tail pages → "Discovered — currently not indexed" (never even crawled)

The reflex is to hunt for a technical bug. I checked all the usual suspects:

Check Result
robots.txt Allow on all SEO paths
pageFetchState SUCCESSFUL
Rendering Full SSR — curl shows the content, not an empty #root
Canonical Self-canonical, consistent
noindex None — INDEXING_ALLOWED

Everything was green. It wasn't a technical problem. That's the trap with this failure mode: nothing is broken, Google just decided the site wasn't worth the index quota.

The real diagnosis

Two things, neither of which a code fix can directly force:

1. New-domain authority (the "sandbox"). A brand-new domain gets a burst of exploratory crawling, then Google reclaims index quota until the domain earns trust. The 05-30 cliff is exactly that reclamation. This is normal and mostly a function of time + backlinks.

2. Thin content at scale. 8,000 templated pages where ~89% are near-duplicates with thin data (a station × purpose with 3 matching cafes) sends a "low average quality" signal. Google samples a few, decides the site isn't worth it, and the whole domain's quota suffers.

The four levers that actually move this

There is no API to force-index general pages — Google's Indexing API is officially JobPosting/BroadcastEvent only. So you're left with levers, not buttons:

1. Concentrate crawl budget (cut thin pages)

Counter-intuitively, the fix for "too many unindexed pages" is fewer pages in the sitemap. I removed the 6,000 individual cafe pages and the 2,191 station × purpose combos from the sitemap index — dropping it from ~8,600 to ~560 high-value URLs:

// Before: every station × every purpose (2,191 thin URLs)
for (const st of stations)
  for (const purpose of PURPOSES)
    urls.push(stationPurposeUrl(st, purpose));

// After: station hubs only (313 substantive URLs)
for (const st of stations)
  urls.push(stationUrl(st));
Enter fullscreen mode Exit fullscreen mode

Key nuance: de-submit ≠ de-index. The routes stay live and crawlable via internal links — I'm just not asking Google to spend budget on them. When authority recovers, the loop comes back.

2. Fix internal linking from your highest-authority page

I found the embarrassing one last: my homepage linked to the cafe map zero times. The footer had links to every other content pillar but not the 8,000-page section. The single most-linked page on the domain was passing no equity to the thing I most wanted indexed. One <a> tag fixed that.

3. Build real backlinks

New domains need trust signals from established ones:

  • App Store / Play Store listing → site URL (store pages are high-authority and constantly crawled)
  • Cross-links from sister domains
  • Content like… this post.

4. Manual "Request Indexing" + time

Search Console's URL Inspection → Request Indexing (~10/day) forces a re-crawl of your strongest pages. It's a nudge, not a guarantee — most effective after the above land. Then: 2–6 months of patience.

Takeaways if you're doing programmatic SEO

  1. Don't submit your whole long-tail on a new domain. Earn quota with a tight, high-value sitemap first, then expand.
  2. "Crawled — not indexed" is a quality/authority verdict, not a bug. Stop grepping your renderer.
  3. Your homepage must link to your money section. Check it. Mine didn't.
  4. De-submit, don't de-index when pruning — keep routes crawlable.
  5. There's no magic button. Plan for months, not days.

The map is live and the pruning just shipped — see the Seoul cafe workability map here. I'll post a follow-up when (if!) the index count moves off zero.

Top comments (0)