Comment créer un composant de sélecteur de langue dans TanStack Start v1
Changer de langue tout en restant sur la même page
Problème
Lorsque les utilisateurs changent de langue dans une application multilingue, ils s'attendent à rester sur la même page et à consulter le même contenu dans la nouvelle langue. Un sélecteur de langue mal implémenté traite la sélection de langue comme une navigation vers une destination différente, redirigeant souvent les utilisateurs vers la page d'accueil et leur faisant perdre complètement leur position. Cela interrompt le flux de l'utilisateur et crée de la frustration, particulièrement lorsque les utilisateurs sont au milieu d'un processus ou consultent un contenu spécifique. Le défi consiste à construire un sélecteur qui change uniquement le segment de langue de l'URL tout en préservant le reste du chemin, les paramètres de recherche et le hash.
Solution
Construire un composant de sélection de langue qui lit le chemin de l'URL actuelle et construit des liens pour chaque langue disponible en remplaçant le segment de locale dans le chemin. Extraire la locale actuelle de la structure de l'URL, puis générer de nouveaux chemins pour les autres langues prises en charge en substituant la portion de locale tout en conservant tous les autres segments d'URL intacts. Utiliser ces chemins pour afficher des liens qui permettent aux utilisateurs de changer de langue sans perdre le contexte de leur page actuelle.
Étapes
1. Définir les locales prises en charge
Créer un fichier de configuration qui liste toutes les langues que votre application prend en charge et identifie la locale par défaut.
export const locales = ["en", "fr", "es", "de"] as const;
export type Locale = (typeof locales)[number];
export const defaultLocale: Locale = "en";
Cette configuration sert de source unique de vérité pour les langues disponibles et sera utilisée pour générer les liens du sélecteur.
2. Créer un helper pour extraire la locale actuelle du chemin
Écrivez une fonction utilitaire qui analyse le chemin d'accès et extrait le segment de locale s'il est présent.
import { defaultLocale, locales, type Locale } from "./locales";
export function getLocaleFromPathname(pathname: string): Locale {
const segments = pathname.split("/").filter(Boolean);
const firstSegment = segments[0];
if (firstSegment && locales.includes(firstSegment as Locale)) {
return firstSegment as Locale;
}
return defaultLocale;
}
Cette fonction examine le premier segment du chemin et le renvoie s'il correspond à une locale prise en charge, sinon elle revient à la locale par défaut.
3. Créer un assistant pour construire des chemins localisés
Écrivez une fonction qui prend le chemin d'accès actuel et une locale cible, puis construit un nouveau chemin avec le segment de locale remplacé.
import { defaultLocale, locales, type Locale } from "./locales";
export function getLocalizedPath(
pathname: string,
targetLocale: Locale,
): string {
const segments = pathname.split("/").filter(Boolean);
const firstSegment = segments[0];
const hasLocalePrefix =
firstSegment && locales.includes(firstSegment as Locale);
if (hasLocalePrefix) {
segments[0] = targetLocale;
} else {
segments.unshift(targetLocale);
}
return "/" + segments.join("/");
}
Cette fonction remplace un segment de locale existant ou ajoute la locale cible au début du chemin, garantissant que la nouvelle URL pointe vers la même page dans une langue différente.
4. Construire le composant de sélecteur de langue
Créez un composant qui utilise l'emplacement actuel pour générer des liens pour toutes les langues prises en charge.
import { Link } from "@tanstack/react-router";
import { useLocation } from "@tanstack/react-router";
import { locales, type Locale } from "./locales";
import { getLocaleFromPathname, getLocalizedPath } from "./locale-helpers";
export function LanguageSwitcher() {
const location = useLocation();
const currentLocale = getLocaleFromPathname(location.pathname);
return (
<nav>
<ul>
{locales.map((locale) => {
const isActive = locale === currentLocale;
const localizedPath = getLocalizedPath(location.pathname, locale);
return (
<li key={locale}>
<Link
to={localizedPath}
search={location.search}
hash={location.hash}
aria-current={isActive ? "page" : undefined}
>
{locale.toUpperCase()}
</Link>
</li>
);
})}
</ul>
</nav>
);
}
Le composant lit le chemin d'accès actuel, détermine la locale active et affiche un lien pour chaque langue prise en charge qui préserve la structure de page actuelle, les paramètres de recherche et le fragment de hachage. Les utilisateurs peuvent changer de langue tout en restant sur la même page logique.