Landingpages als eigene Gattung, erster Typ: Mehrere Links

Die sechs noch offenen Typen haben kein fremdes Ziel, auf das man
weiterleiten koennte — sie brauchen eine Seite. Dafuer bekommt der
Typ-Vertrag `hasLandingPage`: /r/[slug] schickt solche Codes auf /s/[slug],
statt `redirectTarget` zu befragen.

Die oeffentlichen Seiten duerfen die Navigation der Anwendung nicht zeigen —
wer einen Code scannt, hat mit „Verwaltung" nichts zu tun. Deshalb liegt das
App-Chrome jetzt in der Routengruppe (app); das Wurzel-Layout traegt nur noch
html und body. Die URLs aendern sich dadurch nicht.
This commit is contained in:
Florian Wilde
2026-08-14 22:27:49 +02:00
parent b3d386b0d2
commit e627f7c372
27 changed files with 678 additions and 124 deletions
+15 -8
View File
@@ -81,14 +81,21 @@ export async function GET(
}
let target: string;
try {
// Der User-Agent geht mit: Typen wie der App-Link entscheiden daran,
// wohin die Weiterleitung führt.
target = qrType.redirectTarget(code.data, {
userAgent: request.headers.get("user-agent") ?? undefined,
});
} catch {
return notFound("Das Ziel dieses Codes ist nicht mehr gültig.");
if (qrType.hasLandingPage) {
// Kein fremdes Ziel — die Seite liefern wir selbst aus. Bewusst relativ,
// damit der Aufruf auf der Adresse bleibt, über die er hereinkam (auch
// wenn das eine nicht registrierte ist, etwa eine IP im LAN).
target = `/s/${slug}`;
} else {
try {
// Der User-Agent geht mit: Typen wie der App-Link entscheiden daran,
// wohin die Weiterleitung führt.
target = qrType.redirectTarget(code.data, {
userAgent: request.headers.get("user-agent") ?? undefined,
});
} catch {
return notFound("Das Ziel dieses Codes ist nicht mehr gültig.");
}
}
// Der Zähler darf die Weiterleitung nicht ausbremsen oder blockieren.