Skip to content
This repository was archived by the owner on Sep 10, 2026. It is now read-only.

Serve a placeholder icon instead of linking one that is not there - #55

Merged
seenu-k merged 1 commit into
mainfrom
fix/placeholder-app-icon
Aug 12, 2026
Merged

seenu-k merged 1 commit into
mainfrom
fix/placeholder-app-icon

Conversation

@seenu-k

@seenu-k seenu-k commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Every page the engine renders linked /favicon.png and /icons/Icon-192.png unconditionally. Those are static assets from the game's own public/, which a fresh scaffold ships holding a single .gitkeep, so until a Flutter web build landed there the browser tab was blank and all four manifest icons 404ed.

An Android-only game never runs build:web, so it stayed that way permanently — even though the download page's hero already had a fallback for exactly this case. The asymmetry is what this fixes.

What changes

No icons in public/ Icons in public/
<link rel="icon" type="image/svg+xml" href="/_eigen/icon/v1/mark.svg"> <link rel="icon" href="/favicon.png"> + apple-touch
manifest lists one scalable icon manifest lists the four PNGs
hero shows the inline mark hero shows Icon-192.png

The mark is served by the worker, drawn in site.primaryColor, and switches its neutral stroke for a dark tab strip. Apple's touch icon is omitted rather than pointed at a missing file, since it has no SVG support; iOS then derives one from the page, which beats a broken request.

It is a placeholder, not a default. The moment favicon.png exists the engine links the game's own icons everywhere and stops serving its own, so the override needs no configuration.

The probe split

hasWebBuild asks for index.html and still gates "Play on the web". The new hasAppIcons asks for favicon.png and gates every icon. These were one question, on the stated grounds that flutter build web emits both together: true for a game that ships on the web, wrong for the case worth supporting.

hasAppIcons checks the response's content type as well as its status, because the scaffold's single-page-application fallback answers 200 OK with index.html for any missing asset once a web build exists. Status alone would read that as an icon and link a web page where an image belongs.

Notes

  • No run_worker_first change needed: under assets_navigation_prefers_asset_serving only navigation requests bypass the Worker, and an icon fetch is a subresource. This is the same route mechanism the bundled fonts already use.
  • The manifest moves from a 24h to a 1h cache. It used to be a constant and now depends on what is in public/, so a day-old copy would hide the very deploy that adds icons.
  • The placeholder is deliberately not immutable: its bytes carry site.primaryColor.

Verification

174 tests pass. Four are new, and they close the branch the suite previously carried as KNOWN GAP: the other side of this branch is untested — including an Android-only game with icons and no web build, and the SPA-fallback false positive.

🤖 Generated with Claude Code

Every engine-rendered page linked `/favicon.png` and `/icons/Icon-192.png`
unconditionally. Those come from the game's own `public/`, which a fresh
scaffold ships holding a single `.gitkeep`, so until a Flutter web build landed
there the browser tab was blank and all four manifest icons 404ed. An
Android-only game, which never runs `build:web`, stayed that way permanently,
even though the download page's hero already had a fallback for exactly this
case.

The shell now links the EigenInteractive mark, served by the worker and drawn
in `site.primaryColor`, and the manifest advertises that one scalable icon
rather than four missing PNGs. Apple's touch icon is omitted rather than
pointed at a missing file, since it has no SVG support.

A placeholder, not a default: the moment `favicon.png` exists in `public/`, the
game's own icons are linked everywhere and this goes unused.

Splits the asset probe in two to make that work. `hasWebBuild` asks for
`index.html` and still gates "Play on the web"; `hasAppIcons` asks for
`favicon.png` and gates every icon. One probe served both on the grounds that
`flutter build web` emits them together, which holds for a game that ships on
the web and fails the case worth supporting. `hasAppIcons` also checks the
content type, because the scaffold's `single-page-application` fallback answers
`200 OK` with `index.html` for any missing asset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@seenu-k
seenu-k merged commit 98d15ee into main Aug 12, 2026
3 checks passed
@seenu-k
seenu-k deleted the fix/placeholder-app-icon branch August 12, 2026 07:58
@eigen-release eigen-release Bot mentioned this pull request Aug 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant