Skip to content

fix(frontend): repair the site icon in link previews - #177

Merged
hanaCasey merged 2 commits into
developfrom
fix/apple-touch-icon-size
Aug 18, 2026
Merged

fix(frontend): repair the site icon in link previews#177
hanaCasey merged 2 commits into
developfrom
fix/apple-touch-icon-size

Conversation

@hanaCasey

@hanaCasey hanaCasey commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Two separate faults behind one report — "the favicon is not showing up properly in social previews". Both are in the frontend's icon set; neither is an auth or routing problem.

1. apple-touch-icon was a 32×32 image (commit 1)

src/app.html pointed both icon links at the same file, static/favicon.png, which is 32×32:

<link rel="icon" type="image/png" sizes="32x32" href="…/favicon.png" />
<link rel="apple-touch-icon" href="…/favicon.png" />

32×32 is correct for a browser tab, but apple-touch-icon is what iMessage, Safari and iOS home screens read, and Apple's guidance is at least 180×180. At 32×32 those clients either upscale it to a blur or ignore it.

Fix: a real 180×180 static/apple-touch-icon.png, with an explicit sizes="180x180". The 32×32 rel="icon" tag is left alone.

2. There was no favicon.ico at all (commit 2)

The reported symptom in Slack was a broken-image glyph where the site icon belongs. Slack does not consume apple-touch-icon, so commit 1 does not address it. Slack's unfurler — like several other crawlers and some browsers — requests /favicon.ico at the site root by hard-coded convention and never reads <link rel="icon"> at all. static/ had no .ico, so that request 404'd.

Worth ruling out explicitly: this is not the auth guard, even though /favicon.ico is absent from PUBLIC_ROUTE_PATTERNS. Static assets are served ahead of hooks.server.tsfavicon.png and og-default.jpg already demonstrate this by loading on unauthenticated pages. It was a plain missing file.

Fix: a multi-resolution static/favicon.ico (16, 32 and 48 px sub-images), declared in app.html without a type or sizes so the more specific 32×32 PNG still wins in browsers that support it.

The asset source

Both new files are rendered from the vector mark already in the repo (static/logos/sdsc.svg) using the same square viewBox, centred on the mark's measured bounding box — so every icon surface shows identical framing. Aspect ratio preserved (no stretching), with a ~5% inset per side so iOS's rounded-corner mask does not crowd the lobes. Transparent background, matching favicon.png. Both stored via git-lfs, like the repo's other binaries.

Deliberately out of scope: no manifest.json / PWA icon set, no change to og-default.jpg, static/social/* or Seo.svelte (the large preview image is a separate concern), no change to the Keycloak theme's favicon.ico.

Test plan

  • Confirmed both premises: favicon.png's IHDR reports 32×32 and both links resolved to it; static/ contained no .ico (the repo's only one is the Keycloak theme's).
  • Measured the mark's tight bounding box in the SVG (x 10.70–57.80, y 12.50–57.50 → 47.10 × 45.00 user units) rather than guessing a crop, and confirmed it clips nothing.
  • Rendered candidate crops at 16/32/48/180 and viewed each magnified. A bleed-to-edge crop flattens the lobes against the left and top edges at small sizes; the chosen inset stays clean at every size.
  • apple-touch-icon.png verified by decoding: 180×180, colour type 6 (RGBA), glyph bbox (9,12)–(170,167) → symmetric insets, aspect 1.0385 vs the source's 1.0467 (antialias rounding, i.e. not stretched), corners fully transparent.
  • favicon.ico verified by parsing the container by hand, not just identify: valid header (type=1, count=3), three frames whose directory entries agree with the actual pixel dimensions, all 32bpp BMP sub-images (not PNG-in-ICO, which some older consumers cannot read), alpha=Blend and pixel (0,0) srgba(0,0,0,0) on every frame.
  • Viewed every committed frame at its real size — full glyph, no clipping, no stretching.
  • prettier --check passes on app.html in the style the tree actually uses, so the diff is only the intended lines.
  • Verified the LFS objects from the far end, not just locally: a fresh clone of this branch downloads both assets at the correct sizes, and their sha256 sums match the committed pointer oids exactly. (git lfs fsck alone only checks the local store; a pointer whose object never uploaded breaks every fresh checkout.)

Note for reviewers: nix run ./tools/nix#treefmt -- components/frontend/src --ci reformats 133 of 135 files in that tree to 4-space, because the treefmt wrapper honours .editorconfig (indent_size = 4) while the tracked sources are prettier-with---no-editorconfig (2-space). That is pre-existing and repo-wide — this PR deliberately matches the tracked style rather than touching it.

Both icon links pointed at static/favicon.png, which is 32x32. That file
is right for a browser tab, but `apple-touch-icon` is what iMessage,
Safari, Slack and most other link-unfurl clients read for the small site
icon on a preview card, and Apple asks for at least 180x180 there. At
32x32 those clients either upscale it to a blur or drop it outright,
which is what "the favicon is not showing up properly in social
previews" was.

Adds a 180x180 apple-touch-icon.png rendered from the vector mark in
static/logos/sdsc.svg (square viewBox centred on the mark's bounding box,
so the glyph keeps its aspect ratio and gains a small inset that iOS's
rounded-corner mask will not crowd), and points the link at it with an
explicit `sizes`. Transparent background, matching favicon.png. The
32x32 `rel="icon"` tag is unchanged.
Shared links rendered a broken-image glyph where the site icon belongs in
Slack's preview card. Slack's unfurler — like several other crawlers and
some browsers — requests /favicon.ico at the site root by hard-coded
convention and never reads <link rel="icon"> at all, and static/ had no
.ico, so that request 404'd. This is separate from the apple-touch-icon
sizing in the previous commit: Slack does not consume apple-touch-icon.

Not an auth-guard problem, despite /favicon.ico being absent from
PUBLIC_ROUTE_PATTERNS: static assets are served ahead of hooks.server.ts,
which favicon.png and og-default.jpg already demonstrate by loading on
unauthenticated pages. It was a plain missing file.

Adds a multi-resolution favicon.ico (16, 32 and 48 px sub-images, 32bpp
with alpha) rendered from the same vector mark and the same square crop as
apple-touch-icon.png, so every icon surface shows identical framing. Also
declares it in app.html for completeness, without a type or sizes so the
existing, more specific 32x32 PNG still wins in browsers that support it.
@hanaCasey hanaCasey changed the title fix(frontend): serve a properly sized apple-touch-icon fix(frontend): repair the site icon in link previews Aug 17, 2026
@hanaCasey
hanaCasey merged commit fb22107 into develop Aug 18, 2026
1 check passed
@hanaCasey
hanaCasey deleted the fix/apple-touch-icon-size branch August 18, 2026 07:19
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