Skip to content

crawl: X-Robots-Tag noindex on every generated image and every /api route (closes ~260 of the 326 'crawled, currently not indexed' URLs) - #2515

Merged
Flotapponnier merged 1 commit into
devfrom
fix/noindex-images-api
Sep 19, 2026
Merged

Flotapponnier merged 1 commit into
devfrom
fix/noindex-images-api

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Search Console "Crawled, currently not indexed" (326): ~200 og/twitter image URLs, ~60 /api/stat|badge|og|llm-context, the rest compare pairs already noindex, static assets and feeds.

  • src/lib/og-response.tsx: ImageResponse wrapper adding X-Robots-Tag: noindex; all 30 construction sites (17 files) use it. Metadata routes ignore next.config headers, hence the wrapper.
  • next.config headers: /api/:path* → X-Robots-Tag: noindex. robots.txt unchanged (LLM crawlers keep fetching the citable JSON).

Verified locally on API, compare/bench/product/chain images, icon and root images.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw

…g: noindex

Search Console "Crawled, currently not indexed" (326 URLs, 2026-09-19):
about 200 are opengraph-image / twitter-image / icon URLs fetched from
og:image meta tags (compare pairs, benches, products, chains), about 60
are /api/stat, /api/badge, /api/og and /api/llm-context, a handful are
compare pages already noindex, static chunks and feeds. Google fetched
each and had to decide; none is a page.

- src/lib/og-response.tsx wraps ImageResponse with X-Robots-Tag: noindex;
  the 30 construction sites in 17 files (metadata image routes, /api/og,
  share cards, icons) go through it. Metadata routes ignore next.config
  headers(), hence the wrapper.
- next.config headers(): /api/:path* carries X-Robots-Tag: noindex.
  robots.txt stays fully open, so GPTBot, ClaudeBot and PerplexityBot
  keep fetching the citable JSON; noindex is not a fetch block.

The remaining entries of the report are the compare pairs (noindex by
design, they move to "Excluded by noindex"), /benchmarks/perp-fees/SOL
(already 308 to lowercase), and two indexable pages Google judged thin
on the old template (/products/cow, /benchmarks/bitcoin-rpc).

Verified locally: /api/stat, /api/badge, /compare/x/opengraph-image,
/benchmarks/x/opengraph-image/default, /products/x/opengraph-image,
/icon, /opengraph-image all answer the header. tsc, eslint, bun test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw
@Flotapponnier
Flotapponnier merged commit b894225 into dev Sep 19, 2026
1 check failed
@Flotapponnier
Flotapponnier deleted the fix/noindex-images-api branch September 19, 2026 16:45
bakabhai993 pushed a commit to bakabhai993/OpenChainBench that referenced this pull request Sep 20, 2026
…g: noindex (ChainBench#2515)

Search Console "Crawled, currently not indexed" (326 URLs, 2026-09-19):
about 200 are opengraph-image / twitter-image / icon URLs fetched from
og:image meta tags (compare pairs, benches, products, chains), about 60
are /api/stat, /api/badge, /api/og and /api/llm-context, a handful are
compare pages already noindex, static chunks and feeds. Google fetched
each and had to decide; none is a page.

- src/lib/og-response.tsx wraps ImageResponse with X-Robots-Tag: noindex;
  the 30 construction sites in 17 files (metadata image routes, /api/og,
  share cards, icons) go through it. Metadata routes ignore next.config
  headers(), hence the wrapper.
- next.config headers(): /api/:path* carries X-Robots-Tag: noindex.
  robots.txt stays fully open, so GPTBot, ClaudeBot and PerplexityBot
  keep fetching the citable JSON; noindex is not a fetch block.

The remaining entries of the report are the compare pairs (noindex by
design, they move to "Excluded by noindex"), /benchmarks/perp-fees/SOL
(already 308 to lowercase), and two indexable pages Google judged thin
on the old template (/products/cow, /benchmarks/bitcoin-rpc).

Verified locally: /api/stat, /api/badge, /compare/x/opengraph-image,
/benchmarks/x/opengraph-image/default, /products/x/opengraph-image,
/icon, /opengraph-image all answer the header. tsc, eslint, bun test.

Claude-Session: https://claude.ai/code/session_01HJgbZCqjR4nvCfcJSzofbw

Co-authored-by: Flotapponnier <florent@mobula.io>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit b894225)
Flotapponnier added a commit that referenced this pull request Oct 1, 2026
Google shows its default globe next to every openchainbench.com result
instead of the logo. The cause is ours: /icon and /apple-icon are served
with `X-Robots-Tag: noindex`.

They go through ogResponse, the helper that stamps that header on every
generated image. Its own comment listed "icons" among them, so this was
deliberate and simply wrong about one case. The header shipped on
2026-09-19 in #2515, which is when the mark would have stopped being
eligible.

The intent was sound. About 200 generated image URLs sat in Search
Console as "Crawled, currently not indexed" because Googlebot fetched
each one from an og:image meta tag and then had to decide about it, and
the header settles that at fetch time. But a favicon is not a share
image. It is the one asset Google has to store and serve beside the
listing, so telling it not to index that asset removes the only thing it
needs. Opengraph and twitter images keep the header; the two icons opt
out through an explicit `indexable: true`.

Verified with the production Host header, since the staging-noindex rule
in next.config.ts fires on any other host and masks this locally:
/icon and /apple-icon now answer with no X-Robots-Tag, while
/opengraph-image and /twitter-image still answer noindex.

Two things this does not fix. /favicon.ico still 404s; Google accepts
the rel="icon" link so it is not required, and changing which URL serves
the mark right now would reset a clock that is about to start. And
Google re-crawls favicons on its own schedule, "several days to several
weeks" by its own documentation, so the globe will persist for a while
after this ships.
Flotapponnier added a commit that referenced this pull request Oct 1, 2026
Google shows its default globe next to every openchainbench.com result
instead of the logo. The cause is ours: /icon and /apple-icon are served
with `X-Robots-Tag: noindex`.

They go through ogResponse, the helper that stamps that header on every
generated image. Its own comment listed "icons" among them, so this was
deliberate and simply wrong about one case. The header shipped on
2026-09-19 in #2515, which is when the mark would have stopped being
eligible.

The intent was sound. About 200 generated image URLs sat in Search
Console as "Crawled, currently not indexed" because Googlebot fetched
each one from an og:image meta tag and then had to decide about it, and
the header settles that at fetch time. But a favicon is not a share
image. It is the one asset Google has to store and serve beside the
listing, so telling it not to index that asset removes the only thing it
needs. Opengraph and twitter images keep the header; the two icons opt
out through an explicit `indexable: true`.

Verified with the production Host header, since the staging-noindex rule
in next.config.ts fires on any other host and masks this locally:
/icon and /apple-icon now answer with no X-Robots-Tag, while
/opengraph-image and /twitter-image still answer noindex.

Two things this does not fix. /favicon.ico still 404s; Google accepts
the rel="icon" link so it is not required, and changing which URL serves
the mark right now would reset a clock that is about to start. And
Google re-crawls favicons on its own schedule, "several days to several
weeks" by its own documentation, so the globe will persist for a while
after this ships.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants