Comment maintenir la locale dans les liens de navigation avec React Router v7
Maintenir la locale lors de la navigation interne
Problème
Lorsque l'information de locale est encodée dans le chemin de l'URL, chaque lien de navigation doit préserver cette locale pour maintenir une expérience utilisateur cohérente. Si un utilisateur navigue sur la version française de votre site et clique sur un lien vers /about, il s'attend à rester en français et à naviguer vers /fr/about. Sans liens tenant compte de la locale, les utilisateurs se retrouvent dans la langue par défaut en pleine session, ce qui brise leur contexte de navigation et les oblige à changer manuellement de langue à nouveau. Cela crée des frictions et compromet l'expérience localisée.
Coder en dur le préfixe de locale dans chaque lien est source d'erreurs et rend le code fragile. Lorsque les utilisateurs naviguent dans l'application, la locale active peut changer, et mettre à jour manuellement des centaines de liens devient insoutenable.
Solution
Créez un composant Link personnalisé qui lit automatiquement la locale actuelle depuis l'URL et l'ajoute en préfixe à tous les chemins de navigation internes. En encapsulant le composant Link de React Router, vous centralisez la gestion de la locale en un seul endroit. Le wrapper extrait le paramètre de locale depuis la route actuelle et garantit que chaque chemin de destination l'inclut, de sorte que la navigation préserve le choix de langue de l'utilisateur sans intervention manuelle.
Cette approche maintient les définitions de liens propres et indépendantes de la locale dans toute votre application tout en garantissant que le contexte de locale accompagne chaque clic.
Étapes
1. Créer un composant wrapper Link tenant compte de la locale
Construisez un composant personnalisé qui utilise useParams pour extraire la locale actuelle depuis l'URL et encapsule le composant Link de React Router pour ajouter la locale en préfixe au chemin de destination.
import { Link, useParams } from "react-router";
import type { LinkProps } from "react-router";
export function LocaleLink({ to, ...props }: LinkProps) {
const { locale } = useParams<{ locale: string }>();
const localizedTo =
typeof to === "string"
? `/${locale}${to.startsWith("/") ? to : `/${to}`}`
: {
...to,
pathname: `/${locale}${to.pathname?.startsWith("/") ? to.pathname : `/${to.pathname}`}`,
};
return <Link to={localizedTo} {...props} />;
}
Ce composant lit le paramètre de locale depuis la route actuelle et préfixe automatiquement tout chemin que vous passez à la prop to, gérant à la fois les formes chaîne et objet.
2. Utilisez le composant LocaleLink dans toute votre application
Remplacez les composants Link standard par LocaleLink partout où vous avez besoin d'une navigation préservant la locale.
import { LocaleLink } from "./LocaleLink";
export function Navigation() {
return (
<nav>
<LocaleLink to="/">Home</LocaleLink>
<LocaleLink to="/about">About</LocaleLink>
<LocaleLink to="/products">Products</LocaleLink>
</nav>
);
}
Lorsqu'un utilisateur sur /fr/products clique sur le lien À propos, il navigue vers /fr/about. Le préfixe de locale est ajouté automatiquement sans encombrer la définition du lien.
3. Gérez les cas particuliers pour les chemins absolus et les liens externes
Étendez le wrapper pour détecter quand un chemin inclut déjà la locale ou pointe vers une URL externe, évitant ainsi le double préfixage ou la rupture de la navigation externe.
import { Link, useParams } from "react-router";
import type { LinkProps } from "react-router";
export function LocaleLink({ to, ...props }: LinkProps) {
const { locale } = useParams<{ locale: string }>();
if (!locale) {
return <Link to={to} {...props} />;
}
const isExternal =
typeof to === "string" &&
(to.startsWith("http://") || to.startsWith("https://"));
const alreadyLocalized =
typeof to === "string" && to.startsWith(`/${locale}/`);
if (isExternal || alreadyLocalized) {
return <Link to={to} {...props} />;
}
const localizedTo =
typeof to === "string"
? `/${locale}${to.startsWith("/") ? to : `/${to}`}`
: {
...to,
pathname: `/${locale}${to.pathname?.startsWith("/") ? to.pathname : `/${to.pathname}`}`,
};
return <Link to={localizedTo} {...props} />;
}
Cela protège contre le double préfixage si un chemin commence déjà par la locale et laisse passer les URL externes inchangées, garantissant que le composant fonctionne de manière fiable dans tous les scénarios de navigation.