| 1 | --- |
| 2 | /** |
| 3 | * The complete `<link rel="icon">` set, shared by every layout so the tags |
| 4 | * can't drift apart. All of these files are emitted by |
| 5 | * `scripts/generate-brand-assets.ts`. |
| 6 | * |
| 7 | * `favicon.svg` carries both themes in one file and scales to any surface; |
| 8 | * modern browsers pick it and ignore the rest. The PNGs are per-theme |
| 9 | * fallbacks selected with `media`, since a media query can't survive |
| 10 | * rasterization. 512 is listed so hi-DPI surfaces (retina bookmark bars, |
| 11 | * install prompts, Android home screens) have a large source rather than an |
| 12 | * upscaled 32. `apple-touch-icon` is opaque and light-only — iOS web clips |
| 13 | * have no dark variant and ignore `media`. |
| 14 | */ |
| 15 | |
| 16 | interface Props { |
| 17 | /** |
| 18 | * Emit the SVG link. Starlight already injects one from its own `favicon` |
| 19 | * config, so the docs layout passes `false` to avoid a duplicate tag. |
| 20 | */ |
| 21 | svg?: boolean; |
| 22 | } |
| 23 | |
| 24 | const { svg = true } = Astro.props; |
| 25 | |
| 26 | /** [size, light href, dark href] — each expands into a media-switched pair. */ |
| 27 | const RASTERS = [ |
| 28 | [16, "/favicon-16.png", "/favicon-16-dark.png"], |
| 29 | [32, "/favicon-32.png", "/favicon-32-dark.png"], |
| 30 | [512, "/icon-512.png", "/icon-512-dark.png"], |
| 31 | ] as const; |
| 32 | --- |
| 33 | |
| 34 | {svg && <link rel="icon" type="image/svg+xml" href="/favicon.svg" />} |
| 35 | { |
| 36 | RASTERS.map(([size, light, dark]) => ( |
| 37 | <> |
| 38 | <link |
| 39 | rel="icon" |
| 40 | type="image/png" |
| 41 | sizes={`${size}x${size}`} |
| 42 | href={light} |
| 43 | media="(prefers-color-scheme: light)" |
| 44 | /> |
| 45 | <link |
| 46 | rel="icon" |
| 47 | type="image/png" |
| 48 | sizes={`${size}x${size}`} |
| 49 | href={dark} |
| 50 | media="(prefers-color-scheme: dark)" |
| 51 | /> |
| 52 | </> |
| 53 | )) |
| 54 | } |
| 55 | <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" /> |