So behalten Sie das Gebietsschema in Navigationslinks in React Router v7 bei

Gebietsschema über interne Navigation hinweg beibehalten

Problem

Wenn Gebietsschemainformationen im URL-Pfad kodiert sind, muss jeder Navigationslink dieses Gebietsschema beibehalten, um eine konsistente Benutzererfahrung zu gewährleisten. Wenn ein Benutzer die französische Version Ihrer Website durchsucht und auf einen Link zu /about klickt, erwartet er, auf Französisch zu bleiben und zu /fr/about zu navigieren. Ohne gebietsschemabewusste Links werden Benutzer mitten in der Sitzung in die Standardsprache versetzt, was ihren Browsing-Kontext unterbricht und sie zwingt, die Sprache erneut manuell zu wechseln. Dies erzeugt Reibung und untergräbt die lokalisierte Erfahrung.

Das Hartcodieren des Gebietsschemapräfixes in jeden Link ist fehleranfällig und macht die Codebasis fragil. Während Benutzer durch die Anwendung navigieren, kann sich das aktive Gebietsschema ändern, und das manuelle Aktualisieren von Hunderten von Links wird nicht mehr tragbar.

Lösung

Erstellen Sie eine benutzerdefinierte Link-Komponente, die automatisch das aktuelle Gebietsschema aus der URL liest und es allen internen Navigationspfaden voranstellt. Durch das Umschließen der Link-Komponente von React Router zentralisieren Sie die Gebietsschemabehandlung an einer Stelle. Der Wrapper extrahiert den Gebietsschemaparameter aus der aktuellen Route und stellt sicher, dass jeder Zielpfad ihn enthält, sodass die Navigation die Sprachwahl des Benutzers ohne manuellen Eingriff beibehält.

Dieser Ansatz hält Linkdefinitionen in Ihrer gesamten Anwendung sauber und gebietsschemaagnostisch, während gleichzeitig garantiert wird, dass der Gebietsschemakontext bei jedem Klick mitreist.

Schritte

Erstellen Sie eine benutzerdefinierte Komponente, die useParams verwendet, um das aktuelle Gebietsschema aus der URL zu extrahieren, und die Link-Komponente Link von React Router umschließt, um das Gebietsschema dem Zielpfad voranzustellen.

import { Link, useParams } from "react-router";
import type { LinkProps } from "react-router";

export function LocaleLink({ to, ...props }: LinkProps) {
  const { locale } = useParams<{ locale: string }>();

  const localizedTo =
    typeof to === "string"
      ? `/${locale}${to.startsWith("/") ? to : `/${to}`}`
      : {
          ...to,
          pathname: `/${locale}${to.pathname?.startsWith("/") ? to.pathname : `/${to.pathname}`}`,
        };

  return <Link to={localizedTo} {...props} />;
}

Diese Komponente liest den Locale-Parameter aus der aktuellen Route und fügt ihn automatisch jedem Pfad hinzu, den Sie an die to-Prop übergeben, wobei sowohl String- als auch Objektformen verarbeitet werden.

Ersetzen Sie Standard-Link-Komponenten durch LocaleLink, wo immer Sie eine Locale-erhaltende Navigation benötigen.

import { LocaleLink } from "./LocaleLink";

export function Navigation() {
  return (
    <nav>
      <LocaleLink to="/">Home</LocaleLink>
      <LocaleLink to="/about">About</LocaleLink>
      <LocaleLink to="/products">Products</LocaleLink>
    </nav>
  );
}

Wenn ein Benutzer auf /fr/products auf den About-Link klickt, navigiert er zu /fr/about. Das Locale-Präfix wird automatisch hinzugefügt, ohne die Link-Definition zu überladen.

Erweitern Sie den Wrapper, um zu erkennen, wann ein Pfad bereits die Locale enthält oder auf eine externe URL verweist, um doppelte Präfixe zu vermeiden oder die externe Navigation nicht zu unterbrechen.

import { Link, useParams } from "react-router";
import type { LinkProps } from "react-router";

export function LocaleLink({ to, ...props }: LinkProps) {
  const { locale } = useParams<{ locale: string }>();

  if (!locale) {
    return <Link to={to} {...props} />;
  }

  const isExternal =
    typeof to === "string" &&
    (to.startsWith("http://") || to.startsWith("https://"));
  const alreadyLocalized =
    typeof to === "string" && to.startsWith(`/${locale}/`);

  if (isExternal || alreadyLocalized) {
    return <Link to={to} {...props} />;
  }

  const localizedTo =
    typeof to === "string"
      ? `/${locale}${to.startsWith("/") ? to : `/${to}`}`
      : {
          ...to,
          pathname: `/${locale}${to.pathname?.startsWith("/") ? to.pathname : `/${to.pathname}`}`,
        };

  return <Link to={localizedTo} {...props} />;
}

Dies schützt vor doppelten Präfixen, wenn ein Pfad bereits mit der Locale beginnt, und lässt externe URLs unverändert durch, sodass die Komponente in allen Navigationsszenarien zuverlässig funktioniert.