import { ImageResponse } from "next/og"; import { routing } from "@/i18n/routing"; import { getSiteSettings, getSiteSettingsMediaBindings } from "./app-config"; const INTERNAL_FAVICON_PATH = "/favicon.ico"; const INTERNAL_APPLE_ICON_PATH = "/apple-icon.png"; const INTERNAL_MANIFEST_PATH = "/manifest.webmanifest"; const DEFAULT_ICON_VERSION = "default"; type SiteIconInput = { siteName: string; faviconAssetId?: string | null; faviconUrl?: string | null; }; type SiteIconUrls = { siteName: string; version: string; faviconHref: string; appleIconHref: string; manifestHref: string; faviconAssetUrl: string | null; }; function appendVersionToUrl(url: string, version: string): string { const base = url.startsWith("http://") || url.startsWith("https://") ? undefined : "https://local.invalid"; const resolved = new URL(url, base); resolved.searchParams.set("v", version); if (base) { return `${resolved.pathname}${resolved.search}${resolved.hash}`; } return resolved.toString(); } function getFallbackLabel(siteName: string): string { const firstCharacter = siteName.trim().charAt(0).toUpperCase() || "M"; return firstCharacter; } export function buildSiteIconUrls(input: SiteIconInput): SiteIconUrls { const siteName = input.siteName.trim() || "Moh"; const version = input.faviconAssetId?.trim() || DEFAULT_ICON_VERSION; return { siteName, version, faviconHref: appendVersionToUrl(INTERNAL_FAVICON_PATH, version), appleIconHref: appendVersionToUrl(INTERNAL_APPLE_ICON_PATH, version), manifestHref: appendVersionToUrl(INTERNAL_MANIFEST_PATH, version), faviconAssetUrl: input.faviconUrl ? appendVersionToUrl(input.faviconUrl, version) : null, }; } export async function getDynamicSiteIconUrls(): Promise { const [settings, bindings] = await Promise.all([getSiteSettings(), getSiteSettingsMediaBindings()]); const defaultLocaleSettings = settings.locales[routing.defaultLocale]; return buildSiteIconUrls({ siteName: defaultLocaleSettings.siteName, faviconAssetId: bindings.favicon?.assetId, faviconUrl: bindings.favicon?.url, }); } export function buildFallbackIconResponse(siteName: string, size: number) { const label = getFallbackLabel(siteName); return new ImageResponse( (
{label}
), { width: size, height: size, headers: { "Cache-Control": "no-store, max-age=0", }, }, ); }