From 89a75c94caa11cc0444f9ab61407a0e34fc7c52a Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Sat, 16 Aug 2025 13:22:00 -0600 Subject: [PATCH] docs: document favicon generation; chore: add generate-favicon script and yarn task --- README.md | 14 ++++++++++++++ package.json | 1 + tools/generate-favicon.sh | 40 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100755 tools/generate-favicon.sh diff --git a/README.md b/README.md index 25b5821..b9a2de9 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,17 @@ bun run preview ``` Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. + +## Favicons + +The SVG favicon is the source of truth: `public/favicon.svg`. + +Generate a multi-size `favicon.ico` from the SVG using rsvg-convert + ImageMagick: + +```bash +yarn favicons +``` + +Notes: +- ImageMagick on macOS can have issues loading arbitrary TTFs by file path (RenderFreetype errors). To avoid font lookup issues entirely, this project rasterizes the SVG directly using `rsvg-convert` and then packages the sizes into a single ICO using ImageMagick. +- If browsers fail to load webfonts in an external SVG, consider converting the “b” glyph to paths inside the SVG to guarantee pixel-identical rendering across formats. diff --git a/package.json b/package.json index 846f677..5898baa 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", + "favicons": "bash tools/generate-favicon.sh", "postinstall": "nuxt prepare" }, "dependencies": { diff --git a/tools/generate-favicon.sh b/tools/generate-favicon.sh new file mode 100755 index 0000000..c18d55b --- /dev/null +++ b/tools/generate-favicon.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Generates a multi-size favicon.ico from public/favicon.svg +# Dependencies: +# - rsvg-convert (from librsvg) +# - ImageMagick (magick) +# macOS install: +# brew install librsvg imagemagick + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +SVG_PATH="${ROOT_DIR}/public/favicon.svg" +OUT_ICO_PATH="${ROOT_DIR}/public/favicon.ico" + +if ! command -v rsvg-convert >/dev/null 2>&1; then + echo "ERROR: rsvg-convert not found. Install with: brew install librsvg" >&2 + exit 1 +fi +if ! command -v magick >/dev/null 2>&1; then + echo "ERROR: ImageMagick (magick) not found. Install with: brew install imagemagick" >&2 + exit 1 +fi + +tmp_dir="$(mktemp -d)" +cleanup() { rm -rf "${tmp_dir}"; } +trap cleanup EXIT + +sizes=(16 32 48 64) +pngs=() +for s in "${sizes[@]}"; do + out_png="${tmp_dir}/favicon-${s}.png" + rsvg-convert -w "${s}" -h "${s}" "${SVG_PATH}" -o "${out_png}" + pngs+=("${out_png}") +done + +magick "${pngs[@]}" "${OUT_ICO_PATH}" +echo "Generated ${OUT_ICO_PATH}" + +