pwa: fix offline caching for prayer/faith routes
All checks were successful
CI / update (push) Successful in 1m53s
All checks were successful
CI / update (push) Successful in 1m53s
The glob in sync.ts targeted a nonexistent /src/routes/glaube/ directory instead of the actual [faithLang=faithLang] parameterized route. This meant zero prayer pages were ever precached for offline use. - Fix glob to match [faithLang=faithLang] and expand param segments to both language variants (glaube/faith, gebete/prayers, rosenkranz/rosary) - Extract validPrayerSlugs to shared module for build-time route enumeration - Add faith to service worker cacheable route regex
This commit is contained in:
24
src/lib/data/prayerSlugs.ts
Normal file
24
src/lib/data/prayerSlugs.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
// Valid prayer slugs (both languages) — single source of truth
|
||||
// Used by the [prayer] route for validation and by sync.ts for offline precaching
|
||||
export const validPrayerSlugs = new Set([
|
||||
'das-heilige-kreuzzeichen', 'the-sign-of-the-cross',
|
||||
'gloria-patri',
|
||||
'paternoster', 'our-father',
|
||||
'credo', 'nicene-creed',
|
||||
'ave-maria', 'hail-mary',
|
||||
'salve-regina',
|
||||
'das-fatimagebet', 'fatima-prayer',
|
||||
'gloria',
|
||||
'gebet-zum-hl-erzengel-michael', 'prayer-to-st-michael-the-archangel',
|
||||
'bruder-klaus-gebet', 'prayer-of-st-nicholas-of-flue',
|
||||
'josephgebet-des-hl-papst-pius-x', 'prayer-to-st-joseph-by-pope-st-pius-x',
|
||||
'das-confiteor', 'the-confiteor',
|
||||
'postcommunio',
|
||||
'anima-christi',
|
||||
'prayer-before-a-crucifix', 'gebet-vor-einem-kruzifix',
|
||||
'schutzengel-gebet', 'guardian-angel-prayer',
|
||||
'apostolisches-glaubensbekenntnis', 'apostles-creed',
|
||||
'tantum-ergo',
|
||||
'angelus',
|
||||
'regina-caeli',
|
||||
]);
|
||||
@@ -1,16 +1,55 @@
|
||||
import { saveAllRecipes } from './db';
|
||||
import type { BriefRecipeType, RecipeModelType } from '$types/types';
|
||||
import { validPrayerSlugs } from '$lib/data/prayerSlugs';
|
||||
|
||||
// Discover glaube routes at build time using Vite's glob import
|
||||
const glaubePageModules = import.meta.glob('/src/routes/glaube/**/+page.svelte');
|
||||
const glaubeRoutes = Object.keys(glaubePageModules).map(path => {
|
||||
// Convert file path to route path
|
||||
// /src/routes/glaube/+page.svelte -> /glaube
|
||||
// /src/routes/glaube/angelus/+page.svelte -> /glaube/angelus
|
||||
return path
|
||||
.replace('/src/routes', '')
|
||||
.replace('/+page.svelte', '') || '/glaube';
|
||||
});
|
||||
// Discover faith routes at build time using Vite's glob import
|
||||
// The actual directory is [faithLang=faithLang] with parameterized sub-dirs
|
||||
const faithPageModules = import.meta.glob('/src/routes/\\[faithLang=faithLang\\]/**/+page.svelte');
|
||||
|
||||
// Convert file paths to actual route URLs for both language variants
|
||||
// e.g. /src/routes/[faithLang=faithLang]/[prayers=prayersLang]/+page.svelte
|
||||
// -> /glaube/gebete, /faith/prayers
|
||||
const paramMap: Record<string, [string, string]> = {
|
||||
'[faithLang=faithLang]': ['glaube', 'faith'],
|
||||
'[prayers=prayersLang]': ['gebete', 'prayers'],
|
||||
'[rosary=rosaryLang]': ['rosenkranz', 'rosary'],
|
||||
};
|
||||
|
||||
function expandFaithRoutes(): string[] {
|
||||
const routes: string[] = [];
|
||||
for (const filePath of Object.keys(faithPageModules)) {
|
||||
// Strip prefix and suffix: /src/routes/[faithLang=faithLang]/angelus/+page.svelte -> [faithLang=faithLang]/angelus
|
||||
let route = filePath.replace('/src/routes/', '').replace('/+page.svelte', '');
|
||||
|
||||
// Skip routes with dynamic [prayer] segment — those need explicit slug enumeration
|
||||
if (route.includes('[prayer]')) continue;
|
||||
|
||||
// Generate both language variants by replacing all param segments
|
||||
const segments = route.split('/');
|
||||
const deSegments: string[] = [];
|
||||
const enSegments: string[] = [];
|
||||
for (const seg of segments) {
|
||||
if (paramMap[seg]) {
|
||||
deSegments.push(paramMap[seg][0]);
|
||||
enSegments.push(paramMap[seg][1]);
|
||||
} else {
|
||||
deSegments.push(seg);
|
||||
enSegments.push(seg);
|
||||
}
|
||||
}
|
||||
routes.push('/' + deSegments.join('/'));
|
||||
routes.push('/' + enSegments.join('/'));
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
|
||||
const faithRoutes = expandFaithRoutes();
|
||||
|
||||
// Add individual prayer pages (dynamic [prayer] slug, resolved at build time)
|
||||
for (const slug of validPrayerSlugs) {
|
||||
faithRoutes.push(`/glaube/gebete/${slug}`);
|
||||
faithRoutes.push(`/faith/prayers/${slug}`);
|
||||
}
|
||||
|
||||
export type SyncProgress = {
|
||||
phase: 'recipes' | 'pages' | 'data' | 'images';
|
||||
@@ -133,8 +172,8 @@ async function precacheMainPages(_fetchFn: typeof fetch): Promise<void> {
|
||||
'/recipes/favorites/__data.json'
|
||||
];
|
||||
|
||||
// Add dynamically discovered glaube routes (HTML and __data.json)
|
||||
for (const route of glaubeRoutes) {
|
||||
// Add dynamically discovered faith routes (HTML and __data.json)
|
||||
for (const route of faithRoutes) {
|
||||
pagesToCache.push(route);
|
||||
pagesToCache.push(`${route}/__data.json`);
|
||||
}
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { error } from "@sveltejs/kit";
|
||||
|
||||
// Valid prayer slugs (both languages)
|
||||
const validSlugs = new Set([
|
||||
'das-heilige-kreuzzeichen', 'the-sign-of-the-cross',
|
||||
'gloria-patri',
|
||||
'paternoster', 'our-father',
|
||||
'credo', 'nicene-creed',
|
||||
'ave-maria', 'hail-mary',
|
||||
'salve-regina',
|
||||
'das-fatimagebet', 'fatima-prayer',
|
||||
'gloria',
|
||||
'gebet-zum-hl-erzengel-michael', 'prayer-to-st-michael-the-archangel',
|
||||
'bruder-klaus-gebet', 'prayer-of-st-nicholas-of-flue',
|
||||
'josephgebet-des-hl-papst-pius-x', 'prayer-to-st-joseph-by-pope-st-pius-x',
|
||||
'das-confiteor', 'the-confiteor',
|
||||
'postcommunio',
|
||||
'anima-christi',
|
||||
'prayer-before-a-crucifix', 'gebet-vor-einem-kruzifix',
|
||||
'schutzengel-gebet', 'guardian-angel-prayer',
|
||||
'apostolisches-glaubensbekenntnis', 'apostles-creed',
|
||||
'tantum-ergo',
|
||||
'angelus',
|
||||
'regina-caeli',
|
||||
]);
|
||||
import { validPrayerSlugs } from '$lib/data/prayerSlugs';
|
||||
|
||||
export const load: PageServerLoad = async ({ params, url }) => {
|
||||
if (!validSlugs.has(params.prayer)) {
|
||||
if (!validPrayerSlugs.has(params.prayer)) {
|
||||
throw error(404, 'Prayer not found');
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ sw.addEventListener('fetch', (event) => {
|
||||
// Handle SvelteKit __data.json requests for cacheable routes (recipes, glaube, root)
|
||||
// Cache successful responses, serve from cache when offline
|
||||
const isCacheableDataRoute = url.pathname.includes('__data.json') &&
|
||||
(url.pathname.match(/^\/(rezepte|recipes|glaube)(\/|$)/) || url.pathname === '/__data.json');
|
||||
(url.pathname.match(/^\/(rezepte|recipes|glaube|faith)(\/|$)/) || url.pathname === '/__data.json');
|
||||
|
||||
if (isCacheableDataRoute) {
|
||||
event.respondWith(
|
||||
@@ -193,7 +193,7 @@ sw.addEventListener('fetch', (event) => {
|
||||
|
||||
// Cache successful HTML responses for cacheable pages (using pathname as key)
|
||||
const isCacheablePage = response.ok && (
|
||||
url.pathname.match(/^\/(rezepte|recipes|glaube)(\/|$)/) ||
|
||||
url.pathname.match(/^\/(rezepte|recipes|glaube|faith)(\/|$)/) ||
|
||||
url.pathname === '/'
|
||||
);
|
||||
if (isCacheablePage) {
|
||||
|
||||
Reference in New Issue
Block a user