Skip to content

fix(studio): serve favicon.svg from embedded preview server#806

Merged
miguel-heygen merged 1 commit into
mainfrom
fix/studio-favicon-missing
May 13, 2026
Merged

fix(studio): serve favicon.svg from embedded preview server#806
miguel-heygen merged 1 commit into
mainfrom
fix/studio-favicon-missing

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

Closes #804

Problem

/favicon.svg was not listed as a static route in the embedded preview server (studioServer.ts). Requests for it fell through to the SPA catch-all, which returns index.html. The browser received HTML where it expected an SVG and silently ignored it, leaving the tab with no icon.

The file itself (public/favicon.svgdist/studio/favicon.svg) was already correct and present — it just wasn't being served.

Fix

One-line addition: explicit route for /favicon.svg alongside the existing /assets/* and /icons/* static routes.

The /favicon.svg request was falling through to the SPA catch-all, which
returns index.html. The browser received HTML instead of an SVG and
silently discarded it, leaving the tab with no icon.

Added an explicit route for /favicon.svg alongside the existing /assets/*
and /icons/* static routes.

Closes #804
Copy link
Copy Markdown
Collaborator

@jrusso1020 jrusso1020 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE at 022c487c. Smallest possible fix for the reported issue (#804) — one explicit route alongside the existing /assets/* and /icons/* patterns. Diagnosis is precise: the SPA catch-all was returning index.html for /favicon.svg, so the browser got HTML where it expected SVG and silently dropped it.

Rule 2 — other root-level static files to consider

The same fall-through-to-SPA-catch-all pattern likely affects any other root-level static file the studio expects:

  • /robots.txt
  • /manifest.json
  • /favicon.ico (browser-default fallback when /favicon.svg isn't loaded — though this PR fixes the SVG path so the .ico fallback is moot)
  • /apple-touch-icon.png (iOS Safari)
  • Any future PWA-style assets

Worth a quick ls dist/studio/ (or whatever the public-asset emit target is) to see what else lives at the root. If none of those exist today, this PR is complete; if any do, the same SPA-catch-all trap will silently swallow them.

For the favicon case specifically: most browsers will retry /favicon.ico after /favicon.svg fails (or pre-fetch both in parallel depending on <link> tag presence). If dist/studio/ contains a favicon.ico too, you might want to add /favicon.ico to the route list as well for symmetry — same one-line addition.

Non-blocking. The reported user impact (tab icon missing) is fixed by this one line.

CI

Essentially all green. Lint, Build, Test, Typecheck, Test: runtime contract, Format, File size check, regression, player-perf, Preview parity (in_progress but trending green), CodeQL (all 3 langs), Analyze ✓. The only in_progress checks at review time are the heavier windows-latest jobs and CLI smoke. No reds.

Verdict

APPROVE. Smallest possible PR for a real cosmetic user-visible bug. Ship 🚀

— Rames Jusso (pr-review)

@miguel-heygen miguel-heygen merged commit a52c73e into main May 13, 2026
28 checks passed
@miguel-heygen miguel-heygen deleted the fix/studio-favicon-missing branch May 13, 2026 21:53
Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE at 022c487c. Additive review — @jrusso1020 (Rames) already covered the minimal-fix framing and the Rule 2 question about other root-level static files that could share the SPA-catch-all trap.

Strengths

  • packages/cli/src/server/studioServer.ts:423 — single-line addition slotted in next to the existing /assets/* and /icons/* routes. Diagnosis in the PR body is precise: the SPA catch-all returns index.html for /favicon.svg, browser drops the HTML-typed SVG, tab icon goes missing.
  • Path matches the consumer exactly: packages/studio/index.html declares <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> — same absolute path the new route handles. No 404 risk introduced.

Rule 2 — verified (closing Rames's open question)

Rames flagged the sibling-site concern hypothetically (other root files like robots.txt, manifest.json, favicon.ico, apple-touch-icon.png could share the SPA-catch-all trap). Checked packages/studio/public/ against the contents API at HEAD: only favicon.svg and the icons/ directory exist. No other root-level static files are present, so this PR is genuinely complete — not just complete-conditional-on-no-other-files.

If/when any of those get added later, the same one-line route pattern will be needed and this PR's shape is the template.

CI

All required green at review time (Lint, Build, Test, Typecheck, Format, Test: runtime contract, CodeQL ×3, Preview parity, regression, player-perf, File size check, Smoke: global install). mergeStateStatus: BLOCKED because Render-on-windows + Tests-on-windows + CLI smoke (required) were still in-progress — not failing. No reds.

Notes

  • nit: serveStudioStaticFile resolves under studioDir (packages/cli/src/server/studioServer.ts:417) using c.req.path.slice(1) — fine for /favicon.svg (single segment, no traversal), and the existsSync/isFile() guard catches anything weird. No traversal concern for this PR.

Verdict: APPROVE
Reasoning: Smallest possible fix for a real user-visible bug; path matches the consumer in index.html; verified no sibling root files share the same trap; CI clean.

— Vai

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.

(studio) add hyperframes icon to the preview tab

3 participants