feat: wire CMS redirects plugin into hooks.server.ts
Deploy / verify (push) Successful in 51s
Deploy / deploy (push) Successful in 1m16s

New $lib/redirects.server.ts: lazy-loads GET /api/redirects, exact-match
index with trailing-slash normalisation, 60s TTL with background refresh
(cold start blocks once, subsequent requests get stale cache instantly).

hooks.server.ts: before legacy-redirect fallback, runs lookupRedirect for
GET requests. Editor-defined rules win over hardcoded /blog→/posts etc.
External targets (http://…) drop query; internal targets keep ?search.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-05-21 11:51:45 +02:00
parent 0aa3898e5b
commit c00eb26689
2 changed files with 120 additions and 0 deletions
+19
View File
@@ -4,6 +4,7 @@ import { maintenanceResponse } from '$lib/maintenance.server';
import { TRANSLATION_BUNDLE_SLUG } from '$lib/constants';
import { env as envPublic } from '$env/dynamic/public';
import { logWarn } from '$lib/log.server';
import { lookupRedirect } from '$lib/redirects.server';
import type { Handle } from '@sveltejs/kit';
/**
@@ -62,6 +63,24 @@ export const handle: Handle = async ({ event, resolve }) => {
return maintenanceResponse(200);
}
// CMS-verwaltete Redirects (Admin UI → /admin/plugins/redirects).
// Editor-Regeln gewinnen gegen hardcoded Legacy-Patterns; nur GET, sonst
// brechen POST-Forms beim Pfadwechsel.
if (event.request.method === 'GET') {
const cmsRedirect = await lookupRedirect(event.url.pathname);
if (cmsRedirect) {
const search = event.url.search;
const dest =
cmsRedirect.to.startsWith('http') || !search
? cmsRedirect.to
: `${cmsRedirect.to}${search}`;
return new Response(null, {
status: cmsRedirect.status,
headers: { location: dest },
});
}
}
// Legacy-Pfade (/blog, /p) → /posts, /post. Vor Health-Check, weil
// SvelteKit-Routing/CMS-Calls dafür unnötig.
const redirectTo = legacyRedirectTarget(event.url.pathname);