/** * Renders public/favicon.svg into the raster icons the site links to. * Run with `npm run favicons` after changing the logo; outputs are committed, * so the build never needs this script. */ import { readFile, writeFile } from "node:fs/promises"; import sharp from "sharp"; import pngToIco from "png-to-ico"; const SRC = new URL("../public/favicon.svg", import.meta.url); const OUT = new URL("../public/", import.meta.url); // The patch field, so the opaque Apple icon matches the artwork. const NAVY = "#0e1e2c"; const svg = await readFile(SRC); const png = (size) => sharp(svg, { density: 300 }).resize(size, size).png().toBuffer(); const [i16, i32, i48] = await Promise.all([png(16), png(32), png(48)]); await writeFile(new URL("favicon.ico", OUT), await pngToIco([i16, i32, i48])); await writeFile(new URL("icon-192.png", OUT), await png(192)); await writeFile(new URL("icon-512.png", OUT), await png(512)); // iOS composites its own corner mask and dislikes transparency. await writeFile( new URL("apple-touch-icon.png", OUT), await sharp(svg, { density: 300 }) .resize(180, 180) .flatten({ background: NAVY }) .png() .toBuffer(), ); console.log("favicons written to public/");