diff --git a/src/chrome/brandIcons.ts b/src/chrome/brandIcons.ts new file mode 100644 index 0000000..f92b723 --- /dev/null +++ b/src/chrome/brandIcons.ts @@ -0,0 +1,37 @@ +// Returns a Next.js Metadata `icons` object derived from a Brand. +// Apps drop this into their root layout's `metadata` export to ship +// the brand logo as the favicon — fixes the "favicon 404" every +// consumer of the kit was shipping with. +// +// import type { Metadata } from "next"; +// import { brandIcons } from "@gsc/web-kit/chrome"; +// import { brand } from "@/config/brand"; +// +// export const metadata: Metadata = { +// title: brand.product, +// icons: brandIcons(brand), +// }; + +import type { Brand } from "./types"; + +interface BrandMetaIcons { + icon: { url: string; type?: string }[]; + shortcut?: { url: string; type?: string }[]; + apple?: { url: string; type?: string }[]; +} + +export function brandIcons(brand: Brand): BrandMetaIcons { + const url = brand.faviconUrl ?? brand.logoUrl; + // Heuristic: trust the file extension to set the MIME type. Most + // brand logos in the GoSec assets bucket are SVG. + const type = + /\.svg(\?|$)/i.test(url) ? "image/svg+xml" : + /\.png(\?|$)/i.test(url) ? "image/png" : + /\.ico(\?|$)/i.test(url) ? "image/x-icon" : + undefined; + return { + icon: [{ url, ...(type ? { type } : {}) }], + shortcut: [{ url }], + apple: [{ url }], + }; +} diff --git a/src/chrome/index.ts b/src/chrome/index.ts index cab4cde..45eb523 100644 --- a/src/chrome/index.ts +++ b/src/chrome/index.ts @@ -11,6 +11,7 @@ export { type CustomerOption, } from "./header"; export { useChromeLabels, DEFAULT_CHROME_LABELS } from "./labels"; +export { brandIcons } from "./brandIcons"; export type { AdminShellProps, ActivityFeedItem, diff --git a/src/chrome/types.ts b/src/chrome/types.ts index 2d2d6d3..c3e4a24 100644 --- a/src/chrome/types.ts +++ b/src/chrome/types.ts @@ -61,6 +61,7 @@ export type Brand = { product: string; // "GoSec CRM" logoUrl: string; // full navbar logo logoSmallUrl?: string; // optional compact logo + faviconUrl?: string; // optional favicon override (defaults to logoUrl) websiteUrl: string; // footer brand link supportUrl: string; // subbar Support + footer Support link docsUrl: string; // footer docs link