Comment mémoriser la sélection de langue entre les sessions dans Next.js (Pages Router) v16

Enregistrer le choix de langue explicite de l'utilisateur

Problème

Lorsqu'un utilisateur sélectionne explicitement une langue, ce choix reflète sa préférence et doit avoir la priorité sur la détection automatique à partir des en-têtes du navigateur ou de la géolocalisation. Sans persistance, cette préférence est perdue lorsque le navigateur se ferme ou que la session se termine. Lors de la visite suivante, l'application repart de zéro, obligeant l'utilisateur à sélectionner à nouveau sa langue. Cette répétition signale que l'application ne respecte pas les préférences de l'utilisateur, créant des frictions et diminuant la confiance.

Le défi est double : capturer le choix explicite de l'utilisateur au moment de la sélection et récupérer ce choix lors des visites ultérieures avant l'exécution de toute logique de détection automatique. Si la préférence enregistrée n'est pas vérifiée tôt dans le cycle de vie de la requête, l'utilisateur peut être redirigé en fonction des paramètres du navigateur plutôt que de son choix explicite, sapant ainsi la valeur d'avoir effectué une sélection.

Solution

Enregistrez la sélection de langue de l'utilisateur dans un cookie persistant lorsqu'il choisit explicitement une langue. Lors des futures visites à la racine de l'application, vérifiez ce cookie avant de recourir à la détection de locale basée sur le navigateur. Si une locale enregistrée valide est trouvée, redirigez l'utilisateur vers le chemin racine de cette locale, garantissant que sa préférence est immédiatement respectée.

Cette approche sépare le choix explicite de l'utilisateur de la détection automatique. Le cookie agit comme un signal durable d'intention qui survit aux redémarrages du navigateur et a la priorité sur les signaux transitoires comme l'en-tête Accept-Language. En vérifiant le cookie côté serveur lors de la requête initiale, la redirection se produit avant le rendu de la page, offrant une expérience fluide.

Étapes

Lorsqu'un utilisateur sélectionne une langue, enregistrez son choix dans un cookie qui persiste entre les sessions.

export function setLocalePreference(locale: string) {
  const maxAge = 60 * 60 * 24 * 365;
  document.cookie = `NEXT_LOCALE=${locale}; path=/; max-age=${maxAge}; SameSite=Lax`;
}

Cette fonction écrit un cookie nommé NEXT_LOCALE avec la langue choisie, valide pendant un an. Le paramètre path=/ garantit qu'il est disponible dans toute l'application, et SameSite=Lax fournit une protection CSRF raisonnable tout en permettant l'envoi du cookie lors de la navigation de premier niveau.

2. Appeler la fonction auxiliaire lorsque l'utilisateur sélectionne une langue

Intégrez la fonction auxiliaire dans votre composant de sélection de langue afin que la préférence soit enregistrée immédiatement lors de la sélection.

import { useRouter } from "next/router";
import { setLocalePreference } from "@/lib/locale";

export default function LanguageSwitcher() {
  const router = useRouter();
  const { locales, locale: currentLocale } = router;

  const handleLocaleChange = (newLocale: string) => {
    setLocalePreference(newLocale);
    router.push(router.pathname, router.asPath, { locale: newLocale });
  };

  return (
    <select
      value={currentLocale}
      onChange={(e) => handleLocaleChange(e.target.value)}
    >
      {locales?.map((loc) => (
        <option key={loc} value={loc}>
          {loc.toUpperCase()}
        </option>
      ))}
    </select>
  );
}

Lorsque l'utilisateur modifie la sélection, le cookie est défini et le routeur navigue vers la même page dans la nouvelle langue. Le cookie sera disponible pour toutes les requêtes suivantes.

3. Vérifier la préférence enregistrée sur la page racine

Dans le getServerSideProps de la page racine, lisez le cookie et redirigez vers la langue enregistrée si elle existe et est valide.

import { GetServerSideProps } from "next";

export const getServerSideProps: GetServerSideProps = async (context) => {
  const storedLocale = context.req.cookies.NEXT_LOCALE;
  const { locales, defaultLocale } = context;

  if (
    storedLocale &&
    locales?.includes(storedLocale) &&
    storedLocale !== defaultLocale
  ) {
    return {
      redirect: {
        destination: `/${storedLocale}`,
        permanent: false,
      },
    };
  }

  return {
    redirect: {
      destination: `/${defaultLocale}`,
      permanent: false,
    },
  };
};

export default function RootPage() {
  return null;
}

Cela vérifie si le cookie NEXT_LOCALE existe et contient une langue valide parmi la liste configurée de l'application. Si la langue enregistrée n'est pas celle par défaut, l'utilisateur est redirigé vers la racine de cette langue. Sinon, il est redirigé vers la langue par défaut. La redirection s'effectue côté serveur avant le rendu, garantissant que l'utilisateur arrive immédiatement sur la bonne langue.

4. Configurer le routage des langues dans Next.js

Assurez-vous que votre next.config.js définit les langues prises en charge afin que la logique de redirection puisse valider la préférence enregistrée.

module.exports = {
  i18n: {
    locales: ["en", "fr", "de", "es"],
    defaultLocale: "en",
  },
};

Cette configuration active le routage i18n intégré de Next.js et rend locales et defaultLocale disponibles dans getServerSideProps. La logique de la page racine utilise ces valeurs pour valider le cookie stocké et construire la destination de redirection correcte.