fix: ensure Bible verses are prerendered and served statically
Some checks failed
CI / update (push) Has been cancelled

- Fetch full verse data at build time in +page.server.ts
- Pass preloaded verseData to BibleModal instead of fetching client-side
- Remove onMount fetch logic from BibleModal component
- Add VerseData interface to type definitions
- Update handleCitationClick to pass verseData prop

This ensures all Bible verses are embedded in static HTML during build,
eliminating runtime API calls and improving performance.
This commit is contained in:
2025-12-16 16:01:02 +01:00
parent 2be2e1977b
commit b788a615ba
4 changed files with 37 additions and 38 deletions

View File

@@ -1,35 +1,16 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import type { VerseData } from '$lib/data/mysteryDescriptions';
export let reference: string = ''; export let reference: string = '';
export let title: string = ''; export let title: string = '';
export let verseData: VerseData | null = null;
export let onClose: () => void; export let onClose: () => void;
let book: string = ''; let book: string = verseData?.book || '';
let chapter: number = 0; let chapter: number = verseData?.chapter || 0;
let verses: Array<{ verse: number; text: string }> = []; let verses: Array<{ verse: number; text: string }> = verseData?.verses || [];
let loading = true; let loading = false;
let error = ''; let error = verseData ? '' : 'Keine Versdaten verfügbar';
onMount(async () => {
if (!reference) return;
try {
const response = await fetch(`/api/glaube/bibel/${encodeURIComponent(reference)}`);
if (!response.ok) {
throw new Error('Failed to fetch verses');
}
const data = await response.json();
book = data.book;
chapter = data.chapter;
verses = data.verses;
} catch (err) {
console.error('Error fetching Bible verses:', err);
error = 'Fehler beim Laden der Bibelstelle';
} finally {
loading = false;
}
});
function handleBackdropClick(event: MouseEvent) { function handleBackdropClick(event: MouseEvent) {
if (event.target === event.currentTarget) { if (event.target === event.currentTarget) {

View File

@@ -3,8 +3,15 @@ export interface MysteryReference {
reference: string; reference: string;
} }
export interface VerseData {
book: string;
chapter: number;
verses: Array<{ verse: number; text: string }>;
}
export interface MysteryDescription extends MysteryReference { export interface MysteryDescription extends MysteryReference {
text: string; text: string;
verseData?: VerseData | null;
} }
// Only store references - texts will be fetched at build time // Only store references - texts will be fetched at build time

View File

@@ -1,26 +1,34 @@
import { mysteryReferences, type MysteryDescription } from '$lib/data/mysteryDescriptions'; import { mysteryReferences, type MysteryDescription, type VerseData } from '$lib/data/mysteryDescriptions';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
export const prerender = true; export const prerender = true;
async function fetchBibleText(reference: string, fetch: typeof globalThis.fetch): Promise<string> { async function fetchBibleData(reference: string, fetch: typeof globalThis.fetch): Promise<{ text: string; verseData: VerseData | null }> {
try { try {
const response = await fetch(`/api/glaube/bibel/${encodeURIComponent(reference)}`); const response = await fetch(`/api/glaube/bibel/${encodeURIComponent(reference)}`);
if (!response.ok) { if (!response.ok) {
console.error(`Failed to fetch reference ${reference}:`, response.status); console.error(`Failed to fetch reference ${reference}:`, response.status);
return ''; return { text: '', verseData: null };
} }
const data = await response.json(); const data = await response.json();
// Format the verses into a single text with guillemets // Format the verses into a single text with guillemets
let text = '';
if (data.verses && data.verses.length > 0) { if (data.verses && data.verses.length > 0) {
const text = data.verses.map((v: { verse: number; text: string }) => v.text).join(' '); text = `«${data.verses.map((v: { verse: number; text: string }) => v.text).join(' ')}»`;
return `«${text}»`;
} }
return '';
// Store the full verse data for the modal
const verseData: VerseData = {
book: data.book,
chapter: data.chapter,
verses: data.verses
};
return { text, verseData };
} catch (err) { } catch (err) {
console.error(`Error fetching reference ${reference}:`, err); console.error(`Error fetching reference ${reference}:`, err);
return ''; return { text: '', verseData: null };
} }
} }
@@ -38,11 +46,12 @@ export const load: PageServerLoad = async ({ fetch }) => {
const descriptions: MysteryDescription[] = []; const descriptions: MysteryDescription[] = [];
for (const ref of references) { for (const ref of references) {
const text = await fetchBibleText(ref.reference, fetch); const { text, verseData } = await fetchBibleData(ref.reference, fetch);
descriptions.push({ descriptions.push({
title: ref.title, title: ref.title,
reference: ref.reference, reference: ref.reference,
text text,
verseData
}); });
} }

View File

@@ -190,6 +190,7 @@ let decadeCounters = {
let showModal = false; let showModal = false;
let selectedReference = ''; let selectedReference = '';
let selectedTitle = ''; let selectedTitle = '';
let selectedVerseData = null;
// Function to advance the counter for a specific decade // Function to advance the counter for a specific decade
function advanceDecade(decadeNum) { function advanceDecade(decadeNum) {
@@ -225,9 +226,10 @@ function advanceDecade(decadeNum) {
} }
// Function to handle citation click // Function to handle citation click
function handleCitationClick(reference, title = '') { function handleCitationClick(reference, title = '', verseData = null) {
selectedReference = reference; selectedReference = reference;
selectedTitle = title; selectedTitle = title;
selectedVerseData = verseData;
showModal = true; showModal = true;
} }
@@ -1376,7 +1378,7 @@ l536 389l-209 -629zM1671 934l-370 267l150 436l-378 -271l-371 271q8 -34 15 -68q10
<span class="bible-reference-text">{description.reference}</span> <span class="bible-reference-text">{description.reference}</span>
<button <button
class="bible-reference-button" class="bible-reference-button"
on:click={() => handleCitationClick(description.reference, description.title)} on:click={() => handleCitationClick(description.reference, description.title, description.verseData)}
aria-label="Bibelstelle anzeigen" aria-label="Bibelstelle anzeigen"
> >
📖 📖
@@ -1574,5 +1576,5 @@ Anders als die Geheimnisse in Deutsch ist es üblich beim beten des Rosenkranzes
<!-- Bible citation modal --> <!-- Bible citation modal -->
{#if showModal} {#if showModal}
<BibleModal reference={selectedReference} title={selectedTitle} onClose={() => showModal = false} /> <BibleModal reference={selectedReference} title={selectedTitle} verseData={selectedVerseData} onClose={() => showModal = false} />
{/if} {/if}