Comment détecter les préférences linguistiques des utilisateurs dans React Router v7
Redirection automatique basée sur les préférences du navigateur
Problème
Chaque navigateur envoie un en-tête Accept-Language avec chaque requête HTTP, indiquant les langues préférées de l'utilisateur par ordre de préférence. Cet en-tête contient des informations précieuses sur la langue que l'utilisateur s'attend à voir, pourtant la plupart des applications l'ignorent complètement. Au lieu de cela, elles affichent une langue par défaut—généralement l'anglais—à chaque visiteur, forçant les utilisateurs à chercher manuellement un sélecteur de langue alors que leur navigateur a déjà communiqué leur préférence. Cela crée une friction inutile et une mauvaise première impression, particulièrement pour les utilisateurs internationaux.
Solution
Créer un chargeur pour le chemin racine qui lit l'en-tête Accept-Language de la requête entrante. Analyser l'en-tête pour extraire les langues préférées de l'utilisateur et leurs valeurs de qualité. Comparer les langues préférées avec les locales prises en charge par votre application. Si une correspondance est trouvée, rediriger l'utilisateur vers le chemin de cette locale. Si aucune langue prise en charge ne correspond, rediriger vers une locale par défaut. Cela garantit que les utilisateurs arrivent automatiquement sur une version localisée de votre site, basée sur les préférences qu'ils ont déjà configurées dans leur navigateur.
Étapes
1. Installer une bibliothèque pour analyser l'en-tête Accept-Language
L'en-tête Accept-Language a un format spécifique avec des valeurs de qualité qui nécessite une analyse minutieuse. Utilisez une bibliothèque dédiée pour gérer cela correctement.
npm install accept-language-parser
Cette bibliothèque analyse la chaîne d'en-tête en une liste ordonnée de préférences linguistiques, gérant les valeurs de qualité et les cas particuliers conformément à la spécification HTTP.
2. Définir vos locales prises en charge
Créez un fichier d'aide qui liste les locales que votre application prend en charge et spécifie une solution de repli par défaut.
export const supportedLocales = ["en", "fr", "de", "es", "ja"] as const;
export const defaultLocale = "en";
export type Locale = (typeof supportedLocales)[number];
Cela fournit une source unique de vérité pour les langues que votre application peut servir et assure la sécurité des types dans l'ensemble de votre code.
3. Créer un assistant de détection de locale
Construisez une fonction qui prend la valeur de l'en-tête Accept-Language et renvoie la locale supportée correspondant le mieux.
import parser from "accept-language-parser";
import { supportedLocales, defaultLocale, type Locale } from "./locales";
export function detectLocale(acceptLanguageHeader: string | null): Locale {
if (!acceptLanguageHeader) {
return defaultLocale;
}
const languages = parser.parse(acceptLanguageHeader);
for (const lang of languages) {
const code = lang.code.toLowerCase();
if (supportedLocales.includes(code as Locale)) {
return code as Locale;
}
}
return defaultLocale;
}
Cette fonction analyse l'en-tête, parcourt les préférences linguistiques de l'utilisateur par ordre de qualité, et renvoie la première correspondance avec vos locales supportées ou se replie sur la locale par défaut.
4. Configurer la route index racine
Ajoutez une route index à votre configuration de routes qui gérera les requêtes vers le chemin racine.
import { type RouteConfig, index, route } from "@react-router/dev/routes";
export default [
index("routes/index.tsx"),
route(":locale", "routes/locale-root.tsx", []),
] satisfies RouteConfig;
La route index interceptera les requêtes du chemin racine avant que toute autre route ne corresponde, vous permettant d'effectuer la détection de langue et la redirection.
5. Implémenter le chargeur de route index avec détection de langue
Créez le module de route index qui lit l'en-tête Accept-Language et redirige vers le chemin de locale approprié.
import { redirect } from "react-router";
import type { Route } from "./+types/index";
import { detectLocale } from "~/utils/detect-locale";
export async function loader({ request }: Route.LoaderArgs) {
const acceptLanguage = request.headers.get("Accept-Language");
const locale = detectLocale(acceptLanguage);
return redirect(`/${locale}`);
}
Lorsqu'un utilisateur visite le chemin racine, ce chargeur extrait l'en-tête Accept-Language de la requête, détermine la meilleure locale, et les redirige vers le chemin racine de cette locale, garantissant qu'ils voient le contenu dans leur langue préférée dès le premier chargement de page.