church-website/scripts/copy-favicon.mjs
2026-04-09 15:38:32 +02:00

34 lines
1.6 KiB
JavaScript

// White-labeling glue: each client under sites/<id>/ ships its own icon.ico.
// Next.js's App Router picks up the favicon via the file convention at
// src/app/(home)/icon.ico, which can only point to one file. This script runs
// before `next dev` / `next build` (see predev/prebuild in package.json) and
// copies the right per-site icon into that location based on NEXT_PUBLIC_SITE_ID.
// The destination is gitignored so it's treated as a build artifact.
import { copyFileSync, existsSync, readdirSync, statSync } from 'node:fs'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const repoRoot = resolve(__dirname, '..')
// Mirror the default in src/config/site.ts so an unset env var produces the
// same site here as it does at runtime.
const siteId = process.env.NEXT_PUBLIC_SITE_ID || 'dreikoenige'
const sitesDir = join(repoRoot, 'sites')
const source = join(sitesDir, siteId, 'icon.ico')
const destination = join(repoRoot, 'src', 'app', '(home)', 'icon.ico')
// Fail loudly with the list of valid site ids — same UX as the runtime check
// in src/config/site.ts when an unknown NEXT_PUBLIC_SITE_ID is supplied.
if (!existsSync(source)) {
const available = readdirSync(sitesDir)
.filter((entry) => statSync(join(sitesDir, entry)).isDirectory())
.join(', ')
throw new Error(
`[copy-favicon] No icon.ico for site "${siteId}" at ${source}. Available sites: ${available}`,
)
}
copyFileSync(source, destination)
console.log(`[copy-favicon] ${siteId} → src/app/(home)/icon.ico`)