Comment mémoriser la sélection de langue entre les sessions dans TanStack Start v1

Stocker le choix explicite de langue de l'utilisateur

Problème

Lorsqu'un utilisateur sélectionne explicitement une langue, ce choix représente une préférence délibérée qui devrait persister au-delà de la session actuelle du navigateur. Sans persistance, l'application oublie cette préférence à chaque visite, forçant les utilisateurs à resélectionner leur langue à plusieurs reprises. Cela crée des frictions et signale que l'application ne respecte pas les choix des utilisateurs, dégradant l'expérience globale et pouvant potentiellement amener les utilisateurs à abandonner le site avant d'accomplir leurs tâches prévues.

Solution

Stocker le choix de langue de l'utilisateur dans un cookie persistant lorsqu'il fait une sélection explicite. Lors des visites ultérieures, vérifier cette préférence enregistrée avant de recourir aux méthodes de détection automatique comme les en-têtes du navigateur. Si une langue valide est trouvée, rediriger l'utilisateur depuis la racine du site vers le chemin de cette langue, garantissant qu'il arrive directement dans sa locale préférée sans étapes supplémentaires.

Étapes

1. Créer une fonction serveur pour stocker la préférence de langue

Les fonctions serveur vous permettent de définir une logique exclusivement côté serveur qui peut être appelée de n'importe où dans votre application. Définissez une fonction qui écrit la locale sélectionnée dans un cookie.

import { createServerFn } from "@tanstack/react-start";
import { setCookie } from "@tanstack/react-start/server";

const LOCALE_COOKIE = "user_locale";
const COOKIE_MAX_AGE = 60 * 60 * 24 * 365;

export const saveLocalePreference = createServerFn({ method: "POST" })
  .validator((locale: string) => locale)
  .handler(async ({ data }) => {
    setCookie(LOCALE_COOKIE, data, {
      maxAge: COOKIE_MAX_AGE,
      path: "/",
      sameSite: "lax",
    });
    return { success: true };
  });

Cette fonction serveur utilise setCookie de @tanstack/react-start/server pour stocker la préférence de locale, la rendant disponible pour les requêtes futures.

2. Appelez la fonction de sauvegarde lorsque l'utilisateur sélectionne une langue

Dans votre composant de sélection de langue, invoquez la fonction serveur après que l'utilisateur ait fait une sélection.

import { useNavigate } from "@tanstack/react-router";
import { saveLocalePreference } from "./locale-preference";

export function LanguageSwitcher({ currentLocale }: { currentLocale: string }) {
  const navigate = useNavigate();

  const handleLocaleChange = async (newLocale: string) => {
    await saveLocalePreference({ data: newLocale });
    navigate({ to: `/${newLocale}` });
  };

  return (
    <select
      value={currentLocale}
      onChange={(e) => handleLocaleChange(e.target.value)}
    >
      <option value="en">English</option>
      <option value="es">Español</option>
      <option value="fr">Français</option>
    </select>
  );
}

Cela garantit que la préférence est sauvegardée avant de naviguer vers la nouvelle locale.

3. Créez une fonction serveur pour lire la préférence stockée

Définissez une fonction qui récupère la locale stockée à partir du cookie.

import { createServerFn } from "@tanstack/react-start";
import { getCookie } from "@tanstack/react-start/server";

const LOCALE_COOKIE = "user_locale";

export const getStoredLocale = createServerFn({ method: "GET" }).handler(
  async () => {
    const stored = getCookie(LOCALE_COOKIE);
    return stored || null;
  },
);

La fonction getCookie de @tanstack/react-start/server lit la valeur du cookie définie lors des visites précédentes.

4. Vérifiez la préférence stockée sur la route racine

Utilisez la fonction redirect dans le callback beforeLoad d'une route pour déclencher une redirection lorsqu'une préférence stockée est trouvée.

import { createFileRoute, redirect } from "@tanstack/react-router";
import { getStoredLocale } from "./locale-preference";

const SUPPORTED_LOCALES = ["en", "es", "fr"];
const DEFAULT_LOCALE = "en";

export const Route = createFileRoute("/")({
  beforeLoad: async () => {
    const stored = await getStoredLocale();

    if (stored && SUPPORTED_LOCALES.includes(stored)) {
      throw redirect({ to: `/${stored}` });
    }

    throw redirect({ to: `/${DEFAULT_LOCALE}` });
  },
});

Ceci vérifie d'abord la préférence stockée et redirige vers cette locale si elle est valide, sinon il revient à la locale par défaut.

5. Valider la locale stockée par rapport aux langues prises en charge

Ajoutez une validation pour vous assurer que la valeur stockée est une locale reconnue avant la redirection.

import { createFileRoute, redirect } from "@tanstack/react-router";
import { getStoredLocale } from "./locale-preference";

const SUPPORTED_LOCALES = ["en", "es", "fr", "de", "ja"] as const;

function isValidLocale(value: string | null): value is string {
  return value !== null && SUPPORTED_LOCALES.includes(value as any);
}

export const Route = createFileRoute("/")({
  beforeLoad: async () => {
    const stored = await getStoredLocale();
    const locale = isValidLocale(stored) ? stored : "en";
    throw redirect({ to: `/${locale}` });
  },
});

Cela empêche les redirections vers des locales invalides ou non prises en charge, protégeant ainsi contre la falsification de cookies ou les valeurs obsolètes.