feat: add PWA offline support for recipe pages

- Add service worker with caching for build assets, static files, images, and pages
- Add IndexedDB storage for recipes (brief and full data)
- Add offline-db API endpoint for bulk recipe download
- Add offline sync button component in header
- Add offline-shell page for direct navigation fallback
- Pre-cache __data.json for client-side navigation
- Add +page.ts universal load functions with IndexedDB fallback
- Add PWA manifest and icons for installability
- Update recipe page to handle missing data gracefully
This commit is contained in:
2026-01-28 21:38:10 +01:00
parent 9db2009777
commit 9ff30b28cd
24 changed files with 1555 additions and 28 deletions

View File

@@ -0,0 +1,41 @@
import { browser } from '$app/environment';
import { isOffline, canUseOfflineData } from '$lib/offline/helpers';
import { getBriefRecipesBySeason, isOfflineDataAvailable } from '$lib/offline/db';
import { rand_array } from '$lib/js/randomize';
export async function load({ data, params }) {
// On the server, just pass through the server data unchanged
if (!browser) {
return {
...data,
isOffline: false
};
}
// On the client, check if we need to load from IndexedDB
const shouldUseOfflineData = (isOffline() || data?.isOffline || !data?.season?.length) && canUseOfflineData();
if (shouldUseOfflineData) {
try {
const hasOfflineData = await isOfflineDataAvailable();
if (hasOfflineData) {
const month = parseInt(params.month);
const recipes = await getBriefRecipesBySeason(month);
return {
...data,
season: rand_array(recipes),
isOffline: true
};
}
} catch (error) {
console.error('Failed to load offline data:', error);
}
}
// Return server data as-is
return {
...data,
isOffline: false
};
}