Internationaliser les Apps Next.js avec next-intl
Routage par locale, traductions rendues côté serveur, mises en page RTL et SEO hreflang sans flash côté client.
L'internationalisation est une exigence fondamentale pour les applications qui servent des audiences mondiales. À l'ère du App Router de Next.js, des bibliothèques comme next-intl sont devenues la norme de facto pour gérer les traductions, le routage par locale et le SEO dans plusieurs langues. Ce guide présente des modèles éprouvés pour construire des applications React multilingues performantes, bien classées dans les moteurs de recherche et respectueuses des conventions culturelles, y compris les mises en page de droite à gauche.
Choisir une stratégie i18n pour Next.js
Le App Router a changé la façon dont Next.js gère l'internationalisation. La configuration i18n intégrée du Pages Router ne s'applique plus, et les équipes doivent choisir une bibliothèque qui s'intègre au nouveau modèle de routage. next-intl est l'option la plus adoptée car elle fournit un formatage de messages typé, une navigation consciente de la locale et une détection de locale via middleware prête à l'emploi.
Lors de l'évaluation de votre approche, considérez ces décisions architecturales dès le départ :
- Structure d'URL — Basée sur préfixe (
/en/about,/de/about) versus basée sur domaine (en.example.com,de.example.com). - Gestion de la locale par défaut — Si la langue par défaut apparaît dans l'URL ou est déduite des en-têtes.
- Stockage des traductions — Fichiers JSON, intégration CMS ou plateforme de gestion des traductions.
- Comportement de repli — Ce qui se passe lorsqu'une clé de traduction est manquante dans une locale secondaire.
Le routage par préfixe est le défaut recommandé pour la plupart des applications. Il simplifie le déploiement, fonctionne avec l'hébergement statique et donne aux moteurs de recherche des signaux clairs sur les variantes linguistiques.
Configurer le routage par locale
next-intl utilise le middleware Next.js pour détecter la locale préférée de l'utilisateur et réécrire les requêtes vers le segment de locale approprié. Le middleware s'exécute en périphérie, ajoutant une latence négligeable tout en garantissant que chaque page sert le contenu dans la bonne langue.
// middleware.ts
import createMiddleware from "next-intl/middleware";
import { routing } from "./i18n/routing";
export default createMiddleware(routing);
export const config = {
matcher: ["/", "/(de|en|fr|ar)/:path*"],
};
// i18n/routing.ts
import { defineRouting } from "next-intl/routing";
export const routing = defineRouting({
locales: ["en", "de", "fr", "ar"],
defaultLocale: "en",
localePrefix: "always",
});
La structure de votre répertoire app reflète la configuration de locale. Chaque locale obtient son propre segment sous app/[locale]/, et les layouts partagés enveloppent les pages traduites avec une navigation et un pied de page cohérents.
Navigation consciente de la locale
Ne codez jamais en dur les chemins dans les liens. Utilisez les helpers de navigation fournis par next-intl pour générer automatiquement des URL préfixées par locale. Cela évite les liens cassés lorsque vous ajoutez ou supprimez des locales et garantit que le contexte de locale active se propage via la navigation côté client.
import { Link } from "@/i18n/navigation";
export function NavBar() {
return (
<nav>
<Link href="/about">About</Link>
<Link href="/pricing">Pricing</Link>
</nav>
);
}
Organiser les messages de traduction
Structurez vos fichiers de messages pour évoluer avec votre application. Un fichier JSON plat convient aux petits projets, mais des espaces de noms imbriqués évitent les conflits de fusion et améliorent la découvrabilité lorsque votre nombre de traductions atteint des milliers.
- Groupez les messages par fonctionnalité ou page —
home.json,checkout.json,errors.json. - Utilisez des noms de clés descriptifs —
checkout.payment.submitButtonplutôt quebtn1. - Gardez une syntaxe ICU message format cohérente pour la pluralisation et l'interpolation.
- Établissez un flux de revue avec des locuteurs natifs avant de déployer les traductions.
Chargez uniquement les espaces de noms dont une page a besoin pour éviter d'expédier des traductions inutilisées. next-intl supporte le chargement paresseux des modules de messages, ce qui maintient des tailles de bundle initiales gérables même avec des dizaines de locales.
Support des mises en page de droite à gauche
Supporter les langues RTL comme l'arabe et l'hébreu exige plus que traduire des chaînes. La direction de mise en page, l'alignement du texte, le miroir des icônes et la direction des animations doivent tous s'adapter lorsque la locale passe à une langue RTL.
Définissez l'attribut dir sur votre élément HTML racine selon la locale active :
// app/[locale]/layout.tsx
import { getLocale, getMessages } from "next-intl/server";
const rtlLocales = ["ar", "he", "fa"];
export default async function LocaleLayout({ children, params }) {
const locale = await getLocale();
const direction = rtlLocales.includes(locale) ? "rtl" : "ltr";
return (
<html lang={locale} dir={direction}>
<body>{children}</body>
</html>
);
}
Utilisez les propriétés logiques CSS dans toute votre feuille de style. Remplacez margin-left par margin-inline-start, padding-right par padding-inline-end, et text-align: left par text-align: start. Tailwind CSS v4 inclut des utilitaires de propriétés logiques (ms-4, pe-2) qui gèrent cela automatiquement.
SEO pour les sites multilingues
Les moteurs de recherche ont besoin de signaux explicites pour comprendre les relations linguistiques entre les pages. Sans balises hreflang et URL canoniques appropriées, vous risquez des pénalités de contenu dupliqué et un indexage incorrect des locales.
Implémentez ces essentiels SEO :
- Balises link hreflang — Déclarez chaque variante linguistique de chaque page dans l'en-tête du document.
- URL canoniques — Chaque page de locale doit se canonicaliser elle-même, pas vers la locale par défaut.
- Métadonnées traduites — Titre, description et balises Open Graph doivent être localisés, pas copiés depuis la locale par défaut.
- Sitemaps XML — Générez des sitemaps par locale ou un sitemap unifié avec annotations hreflang.
- Données structurées — Localisez le balisage schema JSON-LD pour les résultats de recherche enrichis.
next-intl s'intègre à l'API metadata de Next.js, vous permettant de définir des titres et descriptions spécifiques à la locale dans la fonction generateMetadata de chaque page. Combinez cela avec un générateur de sitemap qui itère sur vos locales et routes pour une couverture complète des moteurs de recherche.
Tests et assurance qualité
Les bugs d'internationalisation sont insidieux car ils n'apparaissent souvent que dans des combinaisons de locales spécifiques. Une clé de traduction manquante peut afficher une chaîne brute en production. Un bug de mise en page RTL peut casser la navigation uniquement en arabe. Intégrez des vérifications automatisées dans votre pipeline CI pour détecter ces problèmes tôt.
- Validez que toutes les locales contiennent le même ensemble de clés de traduction.
- Exécutez des tests de régression visuelle sur les locales RTL pour détecter les cassures de mise en page.
- Testez la détection de locale avec diverses combinaisons d'en-têtes Accept-Language.
- Vérifiez que le formatage des dates, nombres et devises respecte les conventions de locale.
- Contrôlez le poids des pages — assurez-vous que charger tous les messages de locale n'gonfle pas les bundles.
L'internationalisation est un engagement continu, pas une tâche de configuration ponctuelle. À mesure que votre application grandit, les nouvelles fonctionnalités introduisent de nouvelles chaînes, et maintenir la parité des traductions entre les locales exige discipline et outillage. En adoptant next-intl avec un routage par locale structuré, le support RTL et les bonnes pratiques SEO dès le départ, vous construisez une fondation qui évolue gracieusement à mesure que votre audience s'étend à travers les langues et les régions.
Cette lecture vous a plu ?
Un projet ou une idée en tête ? J'aimerais beaucoup en discuter.
Me contacter