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 en visualisant 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 utilisateur et crée de la frustration, en particulier lorsque les utilisateurs sont au cœur d'un workflow ou consultent un contenu spécifique. Le défi consiste à créer un sélecteur qui modifie 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
Créez un composant de sélecteur de langue qui lit le pathname de l'URL actuelle et construit des liens pour chaque langue disponible en remplaçant le segment de locale dans le chemin. Extrayez la locale actuelle de la structure de l'URL, puis générez de nouveaux chemins pour les autres langues prises en charge en substituant la partie locale tout en conservant tous les autres segments d'URL intacts. Utilisez ces chemins pour afficher des liens permettant aux utilisateurs de changer de langue sans perdre le contexte de leur page actuelle.
Étapes
1. Définir les locales prises en charge
Créez un fichier de configuration qui répertorie toutes les langues prises en charge par votre application 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 une fonction utilitaire pour extraire la locale actuelle du pathname
Écrivez une fonction utilitaire qui analyse le pathname 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 inspecte le premier segment du chemin et le retourne s'il correspond à une locale prise en charge, sinon elle revient à la locale par défaut.
3. Créer une fonction utilitaire pour construire des chemins localisés
Écrivez une fonction qui prend le pathname 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 soit un segment de locale existant, soit 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 pathname 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 hash. Les utilisateurs peuvent changer de langue tout en restant sur la même page logique.