Comment détecter les préférences linguistiques des utilisateurs dans TanStack Start v1

Redirection automatique basée sur les préférences du navigateur

Problème

Les navigateurs web envoient un en-tête Accept-Language avec chaque requête HTTP, indiquant les langues préférées de l'utilisateur par ordre de priorité. Cet en-tête fournit des informations précieuses sur la langue avec laquelle l'utilisateur est le plus à l'aise, pourtant de nombreuses applications l'ignorent complètement. Au lieu de cela, elles affichent une langue par défaut—généralement l'anglais—à tous les visiteurs, indépendamment de leurs préférences réelles. Les utilisateurs doivent alors rechercher manuellement un sélecteur de langue, créant une friction inutile alors que l'application dispose déjà des informations nécessaires pour faire un meilleur choix initial.

Cette occasion manquée de personnalisation est particulièrement frustrante pour les non-anglophones qui ont explicitement configuré les préférences linguistiques de leur navigateur. Le résultat est une première impression dégradée et des étapes supplémentaires avant que les utilisateurs puissent interagir avec le contenu dans leur langue préférée.

Solution

Intercepter les requêtes vers le chemin racine et examiner l'en-tête Accept-Language pour déterminer la langue préférée de l'utilisateur. Analyser l'en-tête pour extraire la langue de priorité la plus élevée que votre application prend en charge. Si une correspondance est trouvée, rediriger l'utilisateur vers la route localisée appropriée. Si aucune langue prise en charge n'est trouvée dans l'en-tête, rediriger vers une langue par défaut.

Cette approche respecte automatiquement les préférences des utilisateurs tout en maintenant une structure d'URL claire où chaque langue a son propre préfixe de chemin. La redirection se produit côté serveur avant le rendu de la page, garantissant que les utilisateurs accèdent directement au contenu dans leur langue préférée sans voir un flash de la mauvaise langue.

Étapes

1. Créer un helper pour analyser l'en-tête Accept-Language

L'en-tête Accept-Language contient des codes de langue avec des valeurs de qualité optionnelles qui indiquent l'ordre de préférence. Construisez un analyseur qui extrait ces langues, les trie par priorité et trouve la première correspondance dans votre liste de langues prises en charge.

export function parseAcceptLanguage(
  header: string | null,
  supportedLocales: string[],
): string | null {
  if (!header) {
    return null;
  }

  const languages = header
    .split(",")
    .map((lang) => {
      const [code, qValue] = lang.trim().split(";q=");
      const quality = qValue ? parseFloat(qValue) : 1.0;
      return { code: code.toLowerCase(), quality };
    })
    .sort((a, b) => b.quality - a.quality);

  for (const { code } of languages) {
    const exactMatch = supportedLocales.find(
      (locale) => locale.toLowerCase() === code,
    );
    if (exactMatch) {
      return exactMatch;
    }

    const baseCode = code.split("-")[0];
    const baseMatch = supportedLocales.find((locale) =>
      locale.toLowerCase().startsWith(baseCode),
    );
    if (baseMatch) {
      return baseMatch;
    }
  }

  return null;
}

Cette fonction divise l'en-tête par virgules, extrait les valeurs de qualité, trie par préférence, et vérifie à la fois les correspondances exactes et les correspondances de langue de base par rapport à vos locales prises en charge.

2. Définissez vos locales prises en charge

Créez une configuration qui liste toutes les langues prises en charge par votre application et spécifie celle à utiliser comme solution de repli par défaut.

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

Ces constantes centralisent la configuration de vos langues et facilitent l'ajout ou la suppression des langues prises en charge à mesure que votre application se développe.

3. Créez un gestionnaire de route serveur pour le chemin racine

Ajoutez un gestionnaire GET côté serveur à votre route d'index qui lit l'en-tête Accept-Language, détermine la meilleure locale et redirige l'utilisateur vers le chemin spécifique à la langue appropriée.

import { createFileRoute, redirect } from "@tanstack/react-router";
import { getRequestHeaders } from "@tanstack/react-start/server";

export const Route = createFileRoute("/")({
  server: {
    handlers: {
      GET: async () => {
        const headers = getRequestHeaders();
        const acceptLanguage = headers.get("accept-language");

        const preferredLocale = parseAcceptLanguage(
          acceptLanguage,
          SUPPORTED_LOCALES,
        );

        const targetLocale = preferredLocale || DEFAULT_LOCALE;

        throw redirect({
          to: `/${targetLocale}`,
          statusCode: 302,
        });
      },
    },
  },
});

Ce gestionnaire s'exécute sur le serveur lorsqu'un utilisateur visite le chemin racine, examine ses préférences linguistiques et le redirige immédiatement vers la route de locale la plus adaptée avant que tout code côté client ne s'exécute.

4. Importez la fonction d'assistance

Assurez-vous que la fonction d'analyse est disponible dans votre fichier de route en l'important en haut avec votre configuration de locale.

import { createFileRoute, redirect } from "@tanstack/react-router";
import { getRequestHeaders } from "@tanstack/react-start/server";
import {
  parseAcceptLanguage,
  SUPPORTED_LOCALES,
  DEFAULT_LOCALE,
} from "../lib/locale";

Placez la fonction parseAcceptLanguage et les constantes de locale dans un module partagé afin qu'elles puissent être réutilisées dans toute votre application si nécessaire.