Neue Gruppe "Logo und Favicon" unter Admin > Inhalte mit drei Bildfeldern: Logo (Kopfzeile), optionales Logo fuer dunkle Flaechen (Mobilmenue, Fusszeile, Admin-Leiste; faellt sonst auf das normale Logo zurueck) und Favicon. Leer bleibt alles wie bisher (gezeichnetes Waben-Zeichen bzw. Standard-Icon). - lib/brand.ts liest die Pfade und prueft sie erneut gegen das Upload-Muster, bevor sie in ein src-Attribut gelangen. - Statische app/icon.svg und app/favicon.ico ersetzt durch dynamische app/icon.tsx (512 px PNG) und app/apple-icon.tsx (180 px auf Creme); lib/brand-icon.ts rendert Upload oder Standard-Icon per sharp und liest Dateien nur ueber resolveUploadPath. Cache-Control no-cache, damit ein neues Favicon ohne Tage Verzoegerung erscheint. - /favicon.ico per Rewrite auf /icon, Manifest nutzt /icon. - Hochgeladenes Logo mit fester Hoehe und begrenzter Breite (Kopfzeile mobil 56 px, ab sm 112 px), damit breite Wortmarken nichts sprengen. Uploads bleiben auf Rasterbilder beschraenkt (kein SVG, XSS-Schutz). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
25 lines
991 B
TypeScript
25 lines
991 B
TypeScript
import { getBrandAssets } from "@/lib/brand";
|
|
import { renderBrandIcon } from "@/lib/brand-icon";
|
|
|
|
export const size = { width: 512, height: 512 };
|
|
export const contentType = "image/png";
|
|
|
|
// Das Favicon ist im Admin austauschbar (Inhalte > Logo und Favicon) — nicht
|
|
// zur Build-Zeit einfrieren. "no-cache" statt langem Caching: Browser halten
|
|
// Favicons sonst tagelang fest, ein neues Bild waere nicht zu sehen.
|
|
export const dynamic = "force-dynamic";
|
|
|
|
/**
|
|
* Favicon und Manifest-Icon. 512 px, weil dieselbe Datei auch als Android-
|
|
* Startbildschirm-Icon dient (app/manifest.ts); Browser skalieren fuer den
|
|
* Tab selbst herunter. /favicon.ico wird in next.config.ts hierher
|
|
* umgeleitet.
|
|
*/
|
|
export default async function Icon(): Promise<Response> {
|
|
const { favicon } = await getBrandAssets();
|
|
const png = await renderBrandIcon(favicon, size.width);
|
|
return new Response(new Uint8Array(png), {
|
|
headers: { "Content-Type": contentType, "Cache-Control": "no-cache" },
|
|
});
|
|
}
|