fix favicon delivery and cache invalidation
This commit is contained in:
+12
-7
@@ -12,6 +12,7 @@ import {
|
||||
getSiteSettingsMediaBindings,
|
||||
} from "./app-config";
|
||||
import { AppLocale, getLocalizedPath, resolveLocale } from "./locale";
|
||||
import { buildSiteIconUrls } from "./site-icons";
|
||||
|
||||
function getSiteUrl(): URL {
|
||||
return new URL(process.env.NEXT_PUBLIC_SITE_URL ?? "https://mohfarawati.de");
|
||||
@@ -69,19 +70,23 @@ export function buildAppMetadataFromConfig(
|
||||
): Metadata {
|
||||
const defaultLocaleSettings = settings.locales[routing.defaultLocale];
|
||||
const openGraphImages = buildMetadataImages(bindings.defaultOgImage?.url);
|
||||
const siteIconUrls = buildSiteIconUrls({
|
||||
siteName: defaultLocaleSettings.siteName,
|
||||
faviconAssetId: bindings.favicon?.assetId,
|
||||
faviconUrl: bindings.favicon?.url,
|
||||
});
|
||||
|
||||
return {
|
||||
metadataBase: getSiteUrl(),
|
||||
title: defaultLocaleSettings.siteName,
|
||||
description: defaultLocaleSettings.siteDescription,
|
||||
applicationName: defaultLocaleSettings.siteName,
|
||||
icons: bindings.favicon?.url
|
||||
? {
|
||||
icon: [bindings.favicon.url],
|
||||
shortcut: [bindings.favicon.url],
|
||||
apple: [bindings.favicon.url],
|
||||
}
|
||||
: undefined,
|
||||
manifest: siteIconUrls.manifestHref,
|
||||
icons: {
|
||||
icon: [{ url: siteIconUrls.faviconHref }],
|
||||
shortcut: [{ url: siteIconUrls.faviconHref }],
|
||||
apple: [{ url: siteIconUrls.appleIconHref }],
|
||||
},
|
||||
openGraph: {
|
||||
title: defaultLocaleSettings.siteName,
|
||||
description: defaultLocaleSettings.siteDescription,
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
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<SiteIconUrls> {
|
||||
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(
|
||||
(
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
background: "linear-gradient(135deg, #111827 0%, #0f766e 100%)",
|
||||
color: "#f8fafc",
|
||||
fontSize: size * 0.52,
|
||||
fontWeight: 700,
|
||||
letterSpacing: "-0.08em",
|
||||
borderRadius: size * 0.22,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
),
|
||||
{
|
||||
width: size,
|
||||
height: size,
|
||||
headers: {
|
||||
"Cache-Control": "no-store, max-age=0",
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user