From c3be5c167ddba4a91902445face17774e6dc84bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lohrer?= Date: Tue, 28 Apr 2026 11:36:44 +0200 Subject: [PATCH] fix(spa): clientseitiger 404 nach hydration behoben (D) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Etappe 5 hatte einen bug: nach dem prerendered HTML hat svelteKit beim ersten clientseitigen navigations-tick nochmal load() aufgerufen, das hat im browser-pfad pauschal 404 geworfen. Sichtbarer effekt: seite zeigt kurz den korrekten inhalt, springt dann auf "Post nicht gefunden". Fix-strategie D aus dem chat: - snapshot/output/posts/*.json wird vor dem build nach app/static/snapshot-data/posts/ kopiert (deploy-skript + workflow) - +page.ts im browser-pfad fetcht dann /snapshot-data/posts/.json - 404 nur noch wenn die JSON wirklich nicht existiert (= slug nicht im snapshot) Damit funktionieren sowohl hard-reload (svelteKit hydriert die prerendered page-data direkt) als auch clientseitige navigation zwischen detail-seiten. app/static/snapshot-data/ ist gitignored — wird zur build-zeit aus snapshot/output/ generiert. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/build-deploy.yml | 6 ++++++ app/.gitignore | 3 +++ app/src/routes/[...slug]/+page.ts | 17 +++++++++++++++-- scripts/deploy-svelte.sh | 9 +++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml index 45b6c4c..7c83632 100644 --- a/.github/workflows/build-deploy.yml +++ b/.github/workflows/build-deploy.yml @@ -73,6 +73,12 @@ jobs: run: | deno run --allow-env --allow-read --allow-write --allow-net src/cli.ts + - name: Snapshot-JSONs in app/static kopieren + run: | + rm -rf app/static/snapshot-data + mkdir -p app/static/snapshot-data + cp -r snapshot/output/posts app/static/snapshot-data/posts + - name: Install + build SPA working-directory: ./app run: | diff --git a/app/.gitignore b/app/.gitignore index a9d4f42..cee0762 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -25,3 +25,6 @@ vite.config.ts.timestamp-* # npm *.log test-results/ + +# Snapshot-data wird vor dem build aus snapshot/output/ reinkopiert +static/snapshot-data/ diff --git a/app/src/routes/[...slug]/+page.ts b/app/src/routes/[...slug]/+page.ts index aed1794..c617759 100644 --- a/app/src/routes/[...slug]/+page.ts +++ b/app/src/routes/[...slug]/+page.ts @@ -55,7 +55,7 @@ export const entries: EntryGenerator = async () => { return idx.posts.map((p) => ({ slug: p.slug })) } -export const load: PageLoad = async ({ url }) => { +export const load: PageLoad = async ({ url, fetch }) => { const pathname = url.pathname const legacyDtag = parseLegacyUrl(pathname) @@ -75,5 +75,18 @@ export const load: PageLoad = async ({ url }) => { return { dtag, snapshot } } - throw error(404, 'Post nicht gefunden') + // Im Browser: snapshot per fetch von /snapshot-data/posts/.json laden. + // Beim Hard-Reload einer prerenderten URL nutzt SvelteKit das ins HTML + // serialisierte page-data; bei clientseitiger Navigation kommt der + // request hier durch und holt das fehlende JSON. 404 vom server (slug + // nicht im snapshot) → kein post. + try { + const resp = await fetch(`/snapshot-data/posts/${dtag}.json`) + if (!resp.ok) throw error(404, 'Post nicht gefunden') + const snapshot = (await resp.json()) as PostJson + return { dtag, snapshot } + } catch (err) { + if (err && typeof err === 'object' && 'status' in err) throw err + throw error(404, 'Post nicht gefunden') + } } diff --git a/scripts/deploy-svelte.sh b/scripts/deploy-svelte.sh index 90b5fdb..66ec881 100755 --- a/scripts/deploy-svelte.sh +++ b/scripts/deploy-svelte.sh @@ -89,6 +89,15 @@ if [ ! -f "$SNAPSHOT_DIR/index.json" ]; then exit 1 fi +# Snapshot-JSONs ins SvelteKit-static-verzeichnis kopieren, damit sie +# im build-output unter /snapshot-data/posts/.json gehostet sind. +# Browser-load() macht dann einen fetch auf diesen pfad bei +# clientseitiger navigation zwischen detail-seiten. +echo "Kopiere snapshot/output/posts/ → app/static/snapshot-data/posts/ …" +rm -rf "$ROOT/app/static/snapshot-data" +mkdir -p "$ROOT/app/static/snapshot-data" +cp -r "$SNAPSHOT_DIR/posts" "$ROOT/app/static/snapshot-data/posts" + echo "Baue SvelteKit …" (cd "$ROOT/app" && npm run build >/dev/null 2>&1) || { echo "FEHLER: Build fehlgeschlagen. 'cd app && npm run build' manuell ausführen zum Debuggen." >&2