#!/bin/sh # Rasterise favicon.svg into the icon files clients ask for by path. # # favicon.svg alone is not enough. Two families of request arrive at the web # root for icons no markup ever points at, and both were the top entries in the # 404 report before these files existed: # # /favicon.ico # The unconditional root-path fallback. A client that cannot use an SVG # favicon — Safari, historically — ignores the declared # and asks for this instead, and every non-browser client that never runs # JS (feed readers, the Slack/Discord/WhatsApp/Telegram unfurlers, crawlers) # does the same on the static shell where the head is injected by # catcrafts-head.js rather than served. Nothing declares this file; the # fix is purely that the path resolves. # # /apple-touch-icon.png, /apple-touch-icon-precomposed.png # What iOS/iPadOS and macOS Safari probe at the root when a page declares # no — the Add to Home Screen, Favorites and # Start Page tile. The pages DO declare one now (RenderDocument and # catcrafts-head.js), so the plain path is the one actually in use, and # -precomposed is only reached by clients predating that link being # honoured. ("Precomposed" meant "gloss and rounded corners are already # baked in", from when iOS <7 applied a glossy overlay to the plain one.) # # So only ONE file is produced here: -precomposed is a Caddy rewrite onto # apple-touch-icon.png (deploy/Caddyfile.example). A byte-identical second # copy would be a duplicate to keep in sync in git AND a second entry in # the wasm bundle's VFS — one more file fetched at every boot that nothing # ever reads. The size-suffixed names (apple-touch-icon-180x180.png and # friends) are not produced at all: they have never appeared in the logs, # so shipping them would answer a question nobody asked. # # Checked in rather than built, unlike sitemap.xml and feed.xml. Those drift # with every post; these drift only when favicon.svg is deliberately redrawn, # and generating them in CI would mean installing librsvg and ImageMagick into # the deploy container to produce identical bytes on every push. # # SO: re-run this after ANY edit to favicon.svg, and commit the results. # # Third copy of the same geometry to keep in sync — favicon.svg is the source, # RenderNav in shared/interfaces/Catcrafts.Shared-Views.cppm inlines it as # paths with CSS-variable colours, and these rasters fall out of the SVG here. set -eu cd "$(dirname "$0")/.." SRC="favicon.svg" # The fill from favicon.svg. Only used to flatten the Apple icon: iOS # composites alpha against black and applies its own squircle mask, so the # artwork must reach the edges fully opaque instead of carrying the SVG's own # rounded corners. BG="#0b0d10" for cmd in rsvg-convert magick; do command -v "$cmd" >/dev/null 2>&1 || { echo "make-icons: $cmd not found (pacman -S librsvg imagemagick)" >&2 exit 1 } done TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT # favicon.ico: multi-resolution, transparency kept. The rounded corners read # correctly against both a light and a dark tab bar, and 48px is what Windows # shortcut and some bookmark surfaces pick. for px in 16 32 48; do rsvg-convert -w "$px" -h "$px" "$SRC" -o "$TMP/ico-$px.png" done magick "$TMP/ico-16.png" "$TMP/ico-32.png" "$TMP/ico-48.png" favicon.ico # apple-touch-icon.png: 180x180 is the largest size iOS asks for, and it # downsamples the rest itself. Opaque, per the note on BG above. rsvg-convert -w 180 -h 180 "$SRC" -o "$TMP/touch.png" magick "$TMP/touch.png" -background "$BG" -alpha remove -alpha off \ -strip apple-touch-icon.png echo "make-icons: wrote favicon.ico apple-touch-icon.png"