Wie man Locale-Parameter in URLs in React Router v7 validiert
Nicht unterstützte Locale-Codes elegant behandeln
Problem
Wenn Gebietsschema-Kennungen Teil der URL-Struktur werden, verwandeln sie sich in Benutzereingaben, die beliebige Werte enthalten können. Ein Benutzer könnte manuell /xx/about, /gibberish/contact oder einen anderen ungültigen Gebietsschema-Code in die Adressleiste eingeben. Ohne Validierung muss die Anwendung entscheiden, wie mit diesen ungültigen Eingaben umzugehen ist. Das Zulassen ungültiger Gebietsschemata kann zu fehlenden Übersetzungen, fehlerhafter Formatierung oder Laufzeitfehlern führen, wenn i18n-Bibliotheken versuchen, nicht existierende Gebietsschema-Daten zu laden. Ein stilles Zurückfallen auf ein Standard-Gebietsschema ohne den Benutzer zu informieren, erzeugt Verwirrung darüber, welche Sprache angezeigt wird. Das Anzeigen von Fehlergrenzen oder leeren Seiten lässt Benutzer ohne klaren Weg nach vorne zurück.
Die Herausforderung wird dadurch verstärkt, dass die Gebietsschema-Validierung früh im Anforderungslebenszyklus erfolgen muss, bevor Komponenten gerendert werden und bevor Übersetzungsdaten geladen werden. Wenn die Validierung zu spät erfolgt, hat die Anwendung möglicherweise bereits versucht, gebietsschemaspezifische Ressourcen abzurufen oder i18n-Provider mit ungültiger Konfiguration zu initialisieren, was Ressourcen verschwendet und möglicherweise zu Kaskadenfehlern führt.
Lösung
Validieren Sie den Gebietsschema-Parameter in einem Route-Loader, bevor die Seite gerendert wird. Loader in React Router werden ausgeführt, bevor Komponenten gemountet werden, was sie zum idealen Ort macht, um zu prüfen, ob das angeforderte Gebietsschema in der Liste der unterstützten Sprachen Ihrer Anwendung existiert. Wenn das Gebietsschema gültig ist, lassen Sie die Anfrage normal fortfahren. Wenn das Gebietsschema ungültig ist, leiten Sie den Benutzer sofort zu einem sicheren Fallback um - entweder zum selben Pfad mit einem gültigen Standard-Gebietsschema oder zu einer speziellen Not-Found-Seite, die das Problem erklärt.
Dieser Ansatz verhindert, dass ungültige Gebietsschemata Ihre Komponenten und i18n-Provider erreichen. Durch die Rückgabe einer Umleitungsantwort vom Loader nutzen Sie das integrierte Navigationssystem von React Router, um den Fehler elegant zu behandeln. Die Umleitung erfolgt auf dem Server während des SSR oder auf dem Client während der Navigation, was ein konsistentes Verhalten über Rendering-Strategien hinweg gewährleistet. Benutzer erhalten sofortiges Feedback durch die URL-Änderung, und Ihre Anwendung vermeidet den Versuch, Ressourcen für nicht existierende Gebietsschemata zu laden.
Schritte
1. Definieren Sie Ihre unterstützten Sprachen
Erstellen Sie eine Liste gültiger Sprachcodes, die Ihre Anwendung unterstützt. Diese Liste dient als Quelle der Wahrheit für die Validierung.
export const SUPPORTED_LOCALES = ["en", "es", "fr", "de", "ja"] as const;
export type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];
export function isValidLocale(locale: string): locale is SupportedLocale {
return SUPPORTED_LOCALES.includes(locale as SupportedLocale);
}
Diese Hilfsfunktion bietet typsichere Validierung und kann in Loadern und anderen Teilen Ihrer Anwendung wiederverwendet werden.
2. Fügen Sie die Validierung zu Ihrem Locale-präfixierten Route-Loader hinzu
Exportieren Sie in dem Routenmodul für Ihre Locale-präfixierten Seiten einen Loader, der den Locale-Parameter überprüft und umleitet, wenn er ungültig ist.
import type { Route } from "./+types/page";
import { redirect } from "react-router";
import { isValidLocale } from "~/i18n/locales";
export async function loader({ params }: Route.LoaderArgs) {
const { locale } = params;
if (!locale || !isValidLocale(locale)) {
return redirect("/en/not-found");
}
return { locale };
}
export default function Page({ loaderData }: Route.ComponentProps) {
return (
<div>
<h1>Content in {loaderData.locale}</h1>
</div>
);
}
Der Loader extrahiert die Locale aus der URL, validiert sie und leitet zu einem sicheren Fallback um, wenn die Validierung fehlschlägt. Wenn die Locale gültig ist, gibt er Daten zurück, die Komponenten verwenden können.
3. Konfigurieren Sie Ihre Routen mit Locale-Parametern
Definieren Sie in Ihrer routes.ts-Datei Routen, die die Locale als dynamisches Segment enthalten.
import { type RouteConfig, route } from "@react-router/dev/routes";
export default [
route(":locale/about", "./routes/about.tsx"),
route(":locale/contact", "./routes/contact.tsx"),
route(":locale/not-found", "./routes/not-found.tsx"),
] satisfies RouteConfig;
Jede Route mit einem :locale-Parameter wird ihren Loader aufrufen, wobei die Validierung erfolgt, bevor die Komponente gerendert wird.
4. Erstellen einer Not-Found-Seite für ungültige Locales
Erstellen Sie eine dedizierte Seite, die erklärt, dass die Locale nicht gefunden wurde und Navigationsoptionen anbietet.
import { Link } from "react-router";
import { SUPPORTED_LOCALES } from "~/i18n/locales";
export default function NotFound() {
return (
<div>
<h1>Sprache nicht gefunden</h1>
<p>Die angeforderte Sprache wird nicht unterstützt.</p>
<nav>
<p>Wählen Sie eine Sprache:</p>
<ul>
{SUPPORTED_LOCALES.map((locale) => (
<li key={locale}>
<Link to={`/${locale}`}>{locale.toUpperCase()}</Link>
</li>
))}
</ul>
</nav>
</div>
);
}
Diese Seite bietet klares Feedback und umsetzbare nächste Schritte, die Benutzern helfen, sich von dem Fehler zu erholen, ohne Ihre Anwendung zu verlassen.
5. Hinzufügen einer Catch-All-Route für vollständig ungültige Pfade
Für URLs, die keinem definierten Routenmuster entsprechen, fügen Sie am Ende Ihrer Routenkonfiguration eine Splat-Route hinzu.
import { type RouteConfig, route } from "@react-router/dev/routes";
export default [
route(":locale/about", "./routes/about.tsx"),
route(":locale/contact", "./routes/contact.tsx"),
route(":locale/not-found", "./routes/not-found.tsx"),
route("*", "./routes/catch-all.tsx"),
] satisfies RouteConfig;
Die Splat-Route entspricht jedem Pfad, der nicht mit früheren Routen übereinstimmt, und ermöglicht es Ihnen, vollständig fehlerhafte URLs getrennt von ungültigen Locale-Codes zu behandeln.
6. Optional: Weiterleitung zu einer Standard-Locale anstelle einer Not-Found-Seite
Wenn Sie es vorziehen, ungültige Locales stillschweigend zu korrigieren, anstatt einen Fehler anzuzeigen, leiten Sie zum selben Pfad mit einer Standard-Locale weiter.
import type { Route } from "./+types/page";
import { redirect } from "react-router";
import { isValidLocale } from "~/i18n/locales";
const DEFAULT_LOCALE = "en";
export async function loader({ params, request }: Route.LoaderArgs) {
const { locale } = params;
if (!locale || !isValidLocale(locale)) {
const url = new URL(request.url);
const newPath = url.pathname.replace(/^\/[^/]+/, `/${DEFAULT_LOCALE}`);
return redirect(newPath);
}
return { locale };
}
Dieser Ansatz behält den Rest des URL-Pfads bei und ersetzt nur das ungültige Locale-Segment, was eine reibungslosere Benutzererfahrung bietet, wenn die Locale das einzige Problem ist.