feat(pwa): installierbar mit manifest, icons und offline-katalog
Manifest, Icons (auch maskable und Apple-Touch) und ein Service Worker. Auf dem Handy laesst sich Bricktrack damit auf den Startbildschirm legen und startet ohne Browserleiste; die Verknuepfungen springen direkt zu "Fehlende Sets" und zur Sammlung. Der Service Worker liefert Seiten nach dem Muster "erst Netz, dann Cache": mit Verbindung ist alles aktuell, ohne Verbindung bleibt lesbar, was schon einmal geladen war - genau der Katalog, den man im Keller oder im Laden braucht. Statische Build-Dateien und Set-Bilder kommen aus dem Cache, weil ihre Namen ohnehin unveraenderlich sind. Bewusst nie aus dem Cache: /api/auth, /api/export und der Healthcheck, und nichts ausser GET - eine offline "reservierte" Wunschliste waere eine Luege. Beim Abmelden raeumt die App den Cache, damit auf einem geteilten Geraet keine lesbaren Seiten zurueckbleiben. Icons entstehen reproduzierbar aus einer SVG-Quelle (node scripts/generate-icons.mjs). Refs Phase 2 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { Metadata, Viewport } from 'next';
|
||||
import { ServiceWorkerRegistration } from '@/components/layout/service-worker';
|
||||
import { Toaster } from '@/components/ui/sonner';
|
||||
import './globals.css';
|
||||
|
||||
@@ -9,6 +10,16 @@ export const metadata: Metadata = {
|
||||
},
|
||||
description: 'Sammlung und Wunschlisten für Spielzeug-Sets',
|
||||
applicationName: 'Bricktrack',
|
||||
manifest: '/manifest.webmanifest',
|
||||
icons: {
|
||||
icon: [{ url: '/favicon.png', type: 'image/png', sizes: '32x32' }],
|
||||
apple: [{ url: '/icons/apple-touch-icon.png', sizes: '180x180' }],
|
||||
},
|
||||
appleWebApp: {
|
||||
capable: true,
|
||||
title: 'Bricktrack',
|
||||
statusBarStyle: 'default',
|
||||
},
|
||||
// A private, self-hosted instance never belongs in a search index - and the
|
||||
// public wishlist links are meant to be shared, not found.
|
||||
robots: { index: false, follow: false },
|
||||
@@ -30,6 +41,7 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac
|
||||
<body className="min-h-dvh bg-background text-foreground antialiased">
|
||||
{children}
|
||||
<Toaster position="top-center" richColors closeButton />
|
||||
<ServiceWorkerRegistration />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user