Files
ipal-kit/src/modules/seo/buildIconsMetadata.ts
T

47 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Metadata } from 'next'
type MediaLike =
| { height?: null | number; mimeType?: null | string; url?: null | string; width?: null | number }
| null
| undefined
/**
* Builds Next.js `icons` metadata (favicon / apple-touch-icon) from the panel's
* favicon upload, so the browser tab AND Google get a proper <link rel="icon">.
*
* Why the plugin must do this (not the project): favicon-in-Google has strict
* rules — a real <link rel="icon"> in <head>, square, ≥48×48, at a stable URL.
* Leaving it to each project meant inconsistent hand-rolled tags and no favicon
* in search results. This generates the tags correctly, every time, from the
* panel field.
*
* Favicon is GLOBAL (same across pages), so call this once in the ROOT layout's
* generateMetadata — not per page:
*
* import { buildIconsMetadata } from '@intecion/ipal-kit'
* export async function generateMetadata(): Promise<Metadata> {
* const settings = await getSettings(locale)
* return buildIconsMetadata(settings.favicon)
* }
*
* Google notes: it caches favicons separately and slowly (days/weeks), and only
* shows them for icons it deems valid. Warn on too-small icons at upload time
* (see the media validation hook) so editors don't ship a <48px favicon Google
* will reject.
*/
export function buildIconsMetadata(favicon: MediaLike): Metadata {
const url = favicon?.url
if (!url) {return {}}
const isSvg = favicon?.mimeType === 'image/svg+xml' || url.endsWith('.svg')
return {
icons: {
// Main favicon. SVG scales; PNG should be ≥48×48 (ideally 96 or 192).
icon: isSvg ? [{ type: 'image/svg+xml', url }] : [{ sizes: 'any', url }],
// Apple touch icon (home-screen bookmark on iOS). Reuses the same asset.
apple: [{ url }],
},
}
}