Commencer l'internationalisation (i18n) avec Intlayer et Next.js 15 App Router
Qu'est-ce qu'Intlayer ?
Intlayer est une bibliothèque d'internationalisation (i18n) open-source innovante conçue pour simplifier la prise en charge multilingue dans les applications web modernes. Intlayer s'intègre parfaitement au dernier framework Next.js 15, y compris son puissant App Router. Il est optimisé pour fonctionner avec les Server Components pour un rendu efficace et est entièrement compatible avec Turbopack.
Avec Intlayer, vous pouvez :
- Gérer facilement les traductions à l'aide de dictionnaires déclaratifs au niveau du composant.
- Localiser dynamiquement les métadonnées, itinéraires et contenus.
- Accéder aux traductions à la fois dans les composants côté client et côté serveur.
- Assurer la prise en charge de TypeScript avec des types générés automatiquement, améliorant la complétion automatique et la détection des erreurs.
- Bénéficier de fonctionnalités avancées, comme la détection et le changement dynamique des locales.
Intlayer est compatible avec Next.js 12, 13, 14 et 15. Si vous utilisez Next.js Page Router, vous pouvez vous référer à ce guide. Pour Next.js 12, 13, 14 avec App Router, référez-vous à ce guide.
Guide étape par étape pour configurer Intlayer dans une application Next.js
Étape 1 : Installer les dépendances
Installez les paquets nécessaires en utilisant npm :
npm install intlayer next-intlayer
intlayer
Le paquet central qui fournit des outils d'internationalisation pour la gestion de configuration, la traduction, la déclaration de contenu, la transpilations et les commandes CLI.
next-intlayer
Le paquet qui intègre Intlayer avec Next.js. Il fournit des context providers et des hooks pour l'internationalisation dans Next.js. De plus, il inclut le plugin Next.js pour intégrer Intlayer avec Webpack ou Turbopack, ainsi que du middleware pour détecter la locale préférée de l'utilisateur, gérer les cookies et gérer la redirection d'URL.
Étape 2 : Configurer votre projet
Créez un fichier de configuration pour configurer les langues de votre application :
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [ Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, // Vos autres locales ], defaultLocale: Locales.ENGLISH, },};export default config;
À travers ce fichier de configuration, vous pouvez configurer des URLs localisées, la redirection du middleware, les noms de cookies, l'emplacement et l'extension de vos déclarations de contenu, désactiver les journaux Intlayer dans la console, et plus encore. Pour une liste complète des paramètres disponibles, référez-vous à la documentation sur la configuration.
Étape 3 : Intégrer Intlayer dans votre configuration Next.js
Configurez votre configuration Next.js pour utiliser Intlayer :
import { withIntlayer } from "next-intlayer/server";/** @type {import('next').NextConfig} */const nextConfig = {};export default withIntlayer(nextConfig);
Le plugin withIntlayer() de Next.js est utilisé pour intégrer Intlayer avec Next.js. Il veille à la construction des fichiers de déclaration de contenu et les surveille en mode développement. Il définit les variables d'environnement Intlayer dans les environnements Webpack ou Turbopack. De plus, il fournit des alias pour optimiser la performance et assurer la compatibilité avec les composants serveur.
Étape 4 : Configurer le middleware pour la détection de la locale
Configurez le middleware pour détecter la locale préférée de l'utilisateur :
export { intlayerMiddleware as middleware } from "next-intlayer/middleware";export const config = { matcher: "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",};
Le intlayerMiddleware est utilisé pour détecter la locale préférée de l'utilisateur et le rediriger vers l'URL appropriée comme spécifié dans la configuration. De plus, il permet de sauvegarder la locale préférée de l'utilisateur dans un cookie.
Étape 5 : Définir des itinéraires de locale dynamiques
Retirez tout de RootLayout et remplacez-le par le code suivant :
import type { PropsWithChildren, FC } from "react";import "./globals.css";const RootLayout: FC<PropsWithChildren> = ({ children }) => children;export default RootLayout;
Garder le composant RootLayout vide permet de définir les attributs lang et dir sur la balise <html>.
Pour mettre en œuvre le routage dynamique, fournissez le chemin pour la locale en ajoutant un nouveau layout dans votre répertoire [locale] :
import type { NextLayoutIntlayer } from "next-intlayer";import { Inter } from "next/font/google";import { getHTMLTextDir } from "intlayer";const inter = Inter({ subsets: ["latin"] });const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => { const { locale } = await params; return ( <html lang={locale} dir={getHTMLTextDir(locale)}> <body className={inter.className}>{children}</body> </html> );};export default LocaleLayout;
Le segment de chemin [locale] est utilisé pour définir la locale. Exemple : /en-US/about se référera à en-US et /fr/about à fr.
Ensuite, implémentez la fonction generateStaticParams dans le layout de votre application.
export { generateStaticParams } from "next-intlayer"; // Ligne à insérerconst LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => { /*... Reste du code*/};export default LocaleLayout;
generateStaticParams garantit que votre application préconstruit les pages nécessaires pour toutes les locales, réduisant le calcul à l'exécution et améliorant l'expérience utilisateur. Pour plus de détails, référez-vous à la documentation Next.js sur generateStaticParams.
Étape 6 : Déclarez votre contenu
Créez et gérez vos déclarations de contenu pour stocker les traductions :
import { t, type DeclarationContent } from "intlayer";const pageContent = { key: "page", content: { getStarted: { main: t({ en: "Get started by editing", fr: "Commencez par éditer", es: "Comience por editar", }), pageLink: "src/app/page.tsx", }, },} satisfies DeclarationContent;export default pageContent;
Vos déclarations de contenu peuvent être définies n'importe où dans votre application tant qu'elles sont incluses dans le répertoire contentDir (par défaut, ./src). Et correspondent à l'extension de fichier de déclaration de contenu (par défaut, .content.{ts,tsx,js,jsx,mjs,cjs}). Pour plus de détails, référez-vous à la documentation de la déclaration de contenu.
Étape 7 : Utiliser le contenu dans votre code
Accédez à vos dictionnaires de contenu à travers votre application :
import type { FC } from "react";import { ClientComponentExample } from "@components/ClientComponentExample";import { ServerComponentExample } from "@components/ServerComponentExample";import { type NextPageIntlayer, IntlayerClientProvider } from "next-intlayer";import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";const PageContent: FC = () => { const { title, content } = useIntlayer("page"); return ( <> <p>{content.getStarted.main}</p> <code>{content.getStarted.pageLink}</code> </> );};const Page: NextPageIntlayer = async ({ params }) => { const { locale } = await params; return ( <> <IntlayerServerProvider locale={locale}> <PageContent /> <ServerComponentExample /> <IntlayerClientProvider locale={locale}> <ClientComponentExample /> </IntlayerClientProvider> </IntlayerServerProvider> </> );};export default Page;
- IntlayerClientProvider est utilisé pour fournir la locale aux composants côté client. Il peut être placé dans n'importe quel composant parent, y compris le layout. Cependant, il est recommandé de le placer dans un layout car Next.js partage le code de mise en page entre plusieurs pages, rendant la gestion plus efficace. En utilisant IntlayerClientProvider dans le layout, vous évitez de le réinitialiser pour chaque page, améliorant les performances tout en maintenant un contexte de localisation cohérent dans l'ensemble de votre application.
IntlayerServerProvider est utilisé pour fournir la locale aux enfants du serveur. Il ne peut pas être défini dans le layout.
Le layout et la page ne peuvent pas partager un contexte serveur commun car le système de contexte serveur est basé sur un stockage de données par requête (via le mécanisme de cache de React), ce qui fait que chaque « contexte » est recréé pour différents segments de l'application. Placer le fournisseur dans un layout partagé rompt cette isolation, empêchant la propagation correcte des valeurs de contexte serveur à vos composants serveur.
"use client";import type { FC } from "react";import { useIntlayer } from "next-intlayer";export const ClientComponentExample: FC = () => { const content = useIntlayer("client-component-example"); // Créez une déclaration de contenu associée return ( <div> <h2>{content.title} </h2> <p>{content.content}</p> </div> );};
import type { FC } from "react";import { useIntlayer } from "next-intlayer/server";export const ServerComponentExample: FC = () => { const content = useIntlayer("server-component-example"); // Créez une déclaration de contenu associée return ( <div> <h2>{content.title} </h2> <p>{content.content}</p> </div> );};
Si vous souhaitez utiliser votre contenu dans un attribut string, tel que alt, title, href, aria-label, etc., vous devez appeler la valeur de la fonction, comme :
jsx<img src={content.image.src.value} alt={content.image.value} />
Pour en savoir plus sur le hook useIntlayer, référez-vous à la documentation.
(Optionnel) Étape 8 : Internationalisation de vos métadonnées
Dans le cas où vous souhaitez internationaliser vos métadonnées, telles que le titre de votre page, vous pouvez utiliser la fonction generateMetadata fournie par Next.js. À l'intérieur de la fonction, utilisez la fonction getTranslationContent pour traduire vos métadonnées.
import { type IConfigLocales, getTranslationContent, getMultilingualUrls,} from "intlayer";import type { Metadata } from "next";import type { LocalPromiseParams } from "next-intlayer";export const generateMetadata = async ({ params: { locale },}: LocalPromiseParams): Metadata => { const { locale } = await params; const t = <T>(content: IConfigLocales<T>) => getTranslationContent(content, locale); /** * Génère un objet contenant toutes les URLs pour chaque locale. * * Exemple : * ```ts * getMultilingualUrls('/about'); * * // Renvoie * // { * // en: '/about', * // fr: '/fr/about', * // es: '/es/about', * // } * ``` */ const multilingualUrls = getMultilingualUrls("/"); return { title: t<string>({ en: "My title", fr: "Mon titre", es: "Mi título", }), description: t({ en: "My description", fr: "Ma description", es: "Mi descripción", }), alternates: { canonical: "/", languages: { ...multilingualUrls, "x-default": "/" }, }, openGraph: { url: multilingualUrls[locale], }, };};// ... Reste du code
En savoir plus sur l'optimisation des métadonnées sur la documentation officielle de Next.js.
(Optionnel) Étape 9 : Internationalisation de votre sitemap.xml et robots.txt
Pour internationaliser votre sitemap.xml et robots.txt, vous pouvez utiliser la fonction getMultilingualUrls fournie par Intlayer. Cette fonction vous permet de générer des URLs multilingues pour votre sitemap.
import { getMultilingualUrls } from "intlayer";import type { MetadataRoute } from "next";const sitemap = (): MetadataRoute.Sitemap => [ { url: "https://example.com", alternates: { languages: getMultilingualUrls("https://example.com"), }, }, { url: "https://example.com/login", alternates: { languages: getMultilingualUrls("https://example.com/login"), }, }, { url: "https://example.com/register", alternates: { languages: getMultilingualUrls("https://example.com/register"), }, },];export default sitemap;
import type { MetadataRoute } from "next";import { getMultilingualUrls } from "intlayer";const getAllMultilingualUrls = (urls: string[]) => urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);const robots = (): MetadataRoute.Robots => ({ rules: { userAgent: "*", allow: ["/"], disallow: getAllMultilingualUrls(["/login", "/register"]), }, host: "https://example.com", sitemap: `https://example.com/sitemap.xml`,});export default robots;
En savoir plus sur l'optimisation du sitemap sur la documentation officielle de Next.js. En savoir plus sur l'optimisation de robots.txt sur la documentation officielle de Next.js.
(Optionnel) Étape 10 : Changer la langue de votre contenu
Pour changer la langue de votre contenu, vous pouvez utiliser la fonction setLocale fournie par le hook useLocale. Cette fonction vous permet de définir la locale de l'application et de mettre à jour le contenu en conséquence.
"use client";import type { FC } from "react";import { Locales, getHTMLTextDir, getLocaleName, getLocalizedUrl,} from "intlayer";import { useLocale } from "next-intlayer";import Link from "next/link";export const LocaleSwitcher: FC = () => { const { locale, pathWithoutLocale, availableLocales, setLocale } = useLocale(); return ( <ol> {availableLocales.map((localeItem) => ( <li key={localeItem}> <Link href={getLocalizedUrl(pathWithoutLocale, localeItem)} hrefLang={localeItem} aria-current={locale === localeItem ? "page" : undefined} onClick={(e) => { e.preventDefault(); setLocale(localeItem); }} > <span> {/* Langue dans sa propre locale - e.g. Français */} {getLocaleName(localeItem, locale)} </span> <span dir={getHTMLTextDir(localeItem)} lang={localeItem}> {/* Langue dans la locale actuelle - e.g. Francés avec la locale actuelle réglée sur Locales.SPANISH */} {getLocaleName(localeItem)} </span> <span dir="ltr" lang={Locales.ENGLISH}> {/* Langue en anglais - e.g. French */} {getLocaleName(localeItem, Locales.ENGLISH)} </span> <span> {/* Langue dans sa propre locale - e.g. FR */} {localeItem} </span> </Link> </li> ))} </ol> );};
Références à la documentation :
Configurer TypeScript
Intlayer utilise l'augmentation de module pour bénéficier de TypeScript et renforcer votre codebase.
Assurez-vous que votre configuration TypeScript inclut les types générés automatiquement.
{ // ... Vos configurations TypeScript existantes "include": [ // ... Vos configurations TypeScript existantes "types", // Inclure les types auto-générés ],}
Configuration Git
Il est conseillé d'ignorer les fichiers générés par Intlayer. Cela vous permet d'éviter de les commettre dans votre dépôt Git.
Pour ce faire, vous pouvez ajouter les instructions suivantes à votre fichier .gitignore :
# Ignorer les fichiers générés par Intlayer.intlayer
Si vous avez une idée d’amélioration pour améliorer cette documentation, n’hésitez pas à contribuer en submitant une pull request sur GitHub.
Lien GitHub de la documentation