Skip to content

the favicon told Google not to index it - #2771

Merged
Flotapponnier merged 1 commit into
devfrom
fix/favicon-indexable
Oct 1, 2026
Merged

Flotapponnier merged 1 commit into
devfrom
fix/favicon-indexable

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Symptom

Google shows its default globe next to every openchainbench.com result instead of the logo.

Cause

/icon and /apple-icon are served with X-Robots-Tag: noindex.

Both 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. It shipped 2026-09-19 in #2515.

The intent was sound: ~200 generated image URLs sat in Search Console as "Crawled, currently not indexed" because Googlebot fetched each from an og:image meta and then had to decide about it. 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.

Fix

OG and twitter images keep the header. The two icons opt out with an explicit indexable: true.

Verified with the production Host header, because the staging-noindex rule in next.config.ts fires on any other host and masks this locally:

before after
/icon noindex none
/apple-icon noindex none
/opengraph-image noindex noindex
/twitter-image noindex noindex

Honest about certainty

Google's documentation says noindex is not a fetch block, so strictly Googlebot-Image can still retrieve the file. I cannot cite Google saying "a noindex favicon is dropped". What I can say is that this is the only anomaly in the chain, everything else checks out (crawlable by Googlebot-Image, stable URL, 64×64 which clears their "larger than 48×48" recommendation, square PNG, not robots-blocked), and the header's ship date lines up.

Not fixed here

/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.

Google re-crawls favicons "several days to several weeks" by its own documentation, so the globe will persist for a while after this ships.

408 tests, tsc clean, production build clean.

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
Flotapponnier merged commit d7a0778 into dev Oct 1, 2026
2 checks passed
@Flotapponnier
Flotapponnier deleted the fix/favicon-indexable branch October 1, 2026 23:26
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 2, 2026
The noindex on /icon was the cause of Google's globe and is fixed
(#2771). This is the gap that survived it: /favicon.ico, the
conventional location every crawler and tool probes directly, returned
404. The rel="icon" link is what Google documents as sufficient, so this
is unlikely to be what finally flips the listing, but a 404 on that path
is strictly worse than a file, and it is the single most-requested URL on
any site.

A real multi-size ICO: 16, 32, 48 and 64 px, each a PNG payload, on the
same #f8f3eb background as icon.tsx with 10 % padding so the mark is not
flush to the edge at 16 px.

Two things cost an attempt each and are written into the generator so
they cost nobody else one:

Next's ICO decoder rejects non-RGBA payloads. flatten() produces RGB, so
the first build died on "Format error decoding Ico: The PNG is not in
RGBA format!". ensureAlpha() after flatten() is required, and the script
asserts four channels per size rather than trusting it.

The file is binary and nobody would remember how it was made, so
scripts/build-favicon.mjs regenerates it from public/logo.png and
explains both constraints.

What this does NOT change: the existing <link rel="icon" href="/icon">
stays exactly as it is. Google wants a stable favicon URL and that one
has already been reset once this morning when icon.tsx was edited; it is
not being touched again.
Flotapponnier added a commit that referenced this pull request Oct 2, 2026
…2788)

The noindex on /icon was the cause of Google's globe and is fixed
(#2771). This is the gap that survived it: /favicon.ico, the
conventional location every crawler and tool probes directly, returned
404. The rel="icon" link is what Google documents as sufficient, so this
is unlikely to be what finally flips the listing, but a 404 on that path
is strictly worse than a file, and it is the single most-requested URL on
any site.

A real multi-size ICO: 16, 32, 48 and 64 px, each a PNG payload, on the
same #f8f3eb background as icon.tsx with 10 % padding so the mark is not
flush to the edge at 16 px.

Two things cost an attempt each and are written into the generator so
they cost nobody else one:

Next's ICO decoder rejects non-RGBA payloads. flatten() produces RGB, so
the first build died on "Format error decoding Ico: The PNG is not in
RGBA format!". ensureAlpha() after flatten() is required, and the script
asserts four channels per size rather than trusting it.

The file is binary and nobody would remember how it was made, so
scripts/build-favicon.mjs regenerates it from public/logo.png and
explains both constraints.

What this does NOT change: the existing <link rel="icon" href="/icon">
stays exactly as it is. Google wants a stable favicon URL and that one
has already been reset once this morning when icon.tsx was edited; it is
not being touched again.
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.

1 participant