Wie man die Sprachauswahl über Sitzungen hinweg in React Router v7 speichert

Speichern der expliziten Sprachauswahl des Benutzers

Problem

Wenn ein Benutzer explizit eine Sprache auswählt, spiegelt diese Auswahl seine Präferenz wider und sollte jede automatische Erkennung überschreiben. Ohne Persistenz verschwindet diese Auswahl, wenn der Browser geschlossen wird oder die Sitzung endet. Bei dem nächsten Besuch startet die Anwendung neu und zwingt den Benutzer, seine Sprache erneut auszuwählen. Diese Wiederholung signalisiert, dass die Anwendung seine Präferenzen nicht respektiert, was Reibung erzeugt und das Vertrauen mindert.

Lösung

Speichern Sie die Sprachauswahl des Benutzers an einem persistenten Ort wie einem Cookie, wenn er eine Auswahl trifft. Bei nachfolgenden Besuchen wird diese gespeicherte Präferenz überprüft, bevor auf Browser-Header oder andere Erkennungsmethoden zurückgegriffen wird. Wenn eine gültige gespeicherte Sprache gefunden wird, wird der Benutzer automatisch zur Route dieser Sprache weitergeleitet. Dies stellt sicher, dass seine explizite Auswahl Vorrang hat und über Sitzungen hinweg bestehen bleibt.

Schritte

1. Erstellen eines Cookies zum Speichern der Sprachpräferenz

Definieren Sie ein Cookie, das die vom Benutzer ausgewählte Sprache mit einer langen Ablaufzeit speichert.

import { createCookie } from "react-router";

export const languagePreference = createCookie("language-preference", {
  maxAge: 31536000,
  httpOnly: false,
  secure: process.env.NODE_ENV === "production",
  sameSite: "lax",
});

Dieses Cookie bleibt ein Jahr lang bestehen und ist für clientseitigen Code zum Lesen der Präferenz zugänglich.

2. Hinzufügen einer Aktion zum Speichern der Sprachauswahl

Erstellen Sie eine Aktion, die Sprachauswahl-Formularübermittlungen verarbeitet und die Auswahl im Cookie speichert.

import { redirect } from "react-router";
import type { Route } from "./+types/root";
import { languagePreference } from "./cookies";

export async function action({ request }: Route.ActionArgs) {
  const formData = await request.formData();
  const selectedLanguage = formData.get("language");

  if (typeof selectedLanguage === "string") {
    return redirect(`/${selectedLanguage}`, {
      headers: {
        "Set-Cookie": await languagePreference.serialize(selectedLanguage),
      },
    });
  }

  return redirect("/");
}

Wenn der Benutzer seine Sprachauswahl übermittelt, speichert diese Aktion sie im Cookie und leitet ihn zur entsprechenden Sprachroute weiter.

3. Erstelle eine Sprachauswahlkomponente

Baue eine Formularkomponente, die es Benutzern ermöglicht, ihre bevorzugte Sprache auszuwählen.

import { Form } from "react-router";

export function LanguageSelector({
  currentLanguage,
}: {
  currentLanguage: string;
}) {
  return (
    <Form method="post">
      <select
        name="language"
        defaultValue={currentLanguage}
        onChange={(e) => e.currentTarget.form?.requestSubmit()}
      >
        <option value="en">English</option>
        <option value="es">Español</option>
        <option value="fr">Français</option>
        <option value="de">Deutsch</option>
      </select>
    </Form>
  );
}

Diese Komponente wird automatisch übermittelt, wenn der Benutzer die Auswahl ändert, wodurch die Aktion ausgelöst wird, die die Präferenz speichert.

4. Überprüfe gespeicherte Präferenzen im Root-Loader

Füge dem Root-Route-Loader Logik hinzu, die nach einer gespeicherten Sprachpräferenz sucht und entsprechend weiterleitet.

import { redirect } from "react-router";
import type { Route } from "./+types/root";
import { languagePreference } from "./cookies";

export async function loader({ request }: Route.LoaderArgs) {
  const url = new URL(request.url);
  const cookieHeader = request.headers.get("Cookie");
  const storedLanguage = await languagePreference.parse(cookieHeader);

  if (url.pathname === "/" && storedLanguage) {
    return redirect(`/${storedLanguage}`);
  }

  return null;
}

Wenn ein Benutzer den Root-Pfad besucht, überprüft dieser Loader, ob eine gespeicherte Sprachpräferenz vorhanden ist, und leitet ihn bei Vorhandensein zu seiner gewählten Sprachroute weiter.

5. Validiere die gespeicherte Sprache gegen unterstützte Locales

Stelle sicher, dass die gespeicherte Präferenz gültig ist, bevor sie für die Weiterleitung verwendet wird.

import { redirect } from "react-router";
import type { Route } from "./+types/root";
import { languagePreference } from "./cookies";

const SUPPORTED_LANGUAGES = ["en", "es", "fr", "de"];

export async function loader({ request }: Route.LoaderArgs) {
  const url = new URL(request.url);
  const cookieHeader = request.headers.get("Cookie");
  const storedLanguage = await languagePreference.parse(cookieHeader);

  if (
    url.pathname === "/" &&
    storedLanguage &&
    SUPPORTED_LANGUAGES.includes(storedLanguage)
  ) {
    return redirect(`/${storedLanguage}`);
  }

  return null;
}

Diese Validierung verhindert die Weiterleitung zu ungültigen oder nicht unterstützten Sprachrouten, falls der Cookie-Wert manipuliert wurde oder sich die unterstützten Sprachen seit der Speicherung der Präferenz geändert haben.