Hier ist die instruktive Anleitung für deine IDE (Cursor, Antigravity, etc.). Du kannst diesen Text direkt als Prompt oder Kontext-Datei (`OFFLINE_STRATEGY.md`) in deine IDE kopieren. Es enthält die **Pre-Caching Strategie** (für den Start im Keller) und den **Navigation Fallback** (gegen den White Screen). --- # 🛡️ PWA "Ironclad" Offline Strategy Implementation **Context:** The application fails to load when started completely offline ("Keller-Szenario") or crashes during navigation when the network is flaky. **Goal:** Implement aggressive Pre-Caching for core routes and a robust Navigation Fallback in `public/sw.js`. **Framework:** Next.js (App Router) + Workbox. ## 🚨 Critical Requirements 1. **Preserve Existing Logic:** Do not remove the `skipWaiting()` or `clients.claim()` logic if already present. 2. **App Router Compatibility:** Ensure `_next/data` requests do not cause crashes. 3. **Dexie Integration:** Rely on the existing `useLiveQuery` hooks for data. The Service Worker only needs to deliver the **App Shell**. --- ## 📝 Implementation Instructions for `public/sw.js` Please refactor or append the Service Worker logic to include the following **three mechanics**: ### 1. Define Core Pages (The "Keller" List) Define a list of static routes that *must* work immediately upon installation, even without a network connection. ```javascript // CONFIG: Core pages to pre-cache immediately on install const CORE_PAGES = [ '/', // Dashboard / Home '/tasting/new', // Critical: Add Tasting Screen '/scan', // Critical: Scan Screen '/offline' // Optional: Dedicated offline fallback ]; ``` ### 2. The "Warm Cache" Install Event Add an `install` event listener that aggressively fetches these pages into the cache *before* the user needs them. ```javascript self.addEventListener('install', (event) => { event.waitUntil( caches.open('pages').then((cache) => { console.log('⚡ PWA: Pre-caching core pages for offline usage...'); // { cache: 'reload' } forces a network fetch, ignoring browser http cache return cache.addAll(CORE_PAGES); }) ); self.skipWaiting(); }); ``` ### 3. The Navigation Safety Net (The "Anti-Crash" Logic) Implement a `NavigationRoute` that attempts the network first (with a short timeout), falls back to the cache, and—**critically**—falls back to the Root (`/`) if the specific deep-link is missing from the cache. *Rationale:* In Next.js (SPA), loading `/` from cache is sufficient to bootstrap the React app. The client-side router will then handle the URL, and Dexie will provide the data. ```javascript import { registerRoute, NavigationRoute } from 'workbox-routing'; import { NetworkFirst } from 'workbox-strategies'; import { CacheableResponsePlugin } from 'workbox-cacheable-response'; // Strategy: Network (3s timeout) -> Cache -> Fallback to Root const navigationHandler = async (params) => { try { // 1. Try Network First (Fail fast if poor connection) const strategy = new NetworkFirst({ cacheName: 'pages', networkTimeoutSeconds: 3, plugins: [ new CacheableResponsePlugin({ statuses: [0, 200] }), ], }); return await strategy.handle(params); } catch (error) { // 2. Network failed. Try getting the specific page from cache. const cache = await caches.open('pages'); // params.request.url contains the full URL user is trying to reach let response = await cache.match(params.request); if (response) return response; // 3. CRITICAL FALLBACK: Load the App Shell (Root) // Even if the user requested /tasting/new, serving / allows Next.js to start. // Once React hydrates, it sees the URL is /tasting/new and renders the correct page // using data from Dexie. const fallbackResponse = await cache.match('/'); if (fallbackResponse) { console.log('⚠️ PWA: Serving Root App Shell for offline navigation.'); return fallbackResponse; } // 4. Absolute last resort return new Response('Offline mode unavailable', { status: 504 }); } }; // Apply this handler to all Navigation requests registerRoute(new NavigationRoute(navigationHandler)); ``` ### 4. Handling Next.js Data (RSC) Prevent crashes when `_next/data/...` fetches fail. ```javascript // Swallow errors for RSC data to prevent "Application Error" screens registerRoute( ({ url }) => url.pathname.startsWith('/_next/data/'), new NetworkFirst({ cacheName: 'next-data', networkTimeoutSeconds: 2, plugins: [ { // If offline and not in cache, return empty JSON to keep React alive handlerDidError: async () => new Response(JSON.stringify({}), { headers: { 'Content-Type': 'application/json' } }) } ] }) ); ``` --- ## ✅ Verification Checklist After applying these changes: 1. **Clear Storage:** Unregister old Service Workers and clear Storage in DevTools. 2. **Install:** Load the app once online. Verify `pages` cache contains `/tasting/new`. 3. **Test:** * Go Offline (Airplane Mode). * Reload the page. * Navigate to `/tasting/new`. * **Expectation:** App loads, UI renders, data comes from Dexie. No "No Internet" dino.