Creation:2026-01-10Last update:2026-05-31

    Traduisez votre site Next.js 16 (sans [locale] dans le chemin des pages) avec Intlayer | Internationalisation (i18n)

    www.youtube.com

    Voir Application Template sur GitHub.

    Table des matières

    Pourquoi Intlayer plutôt que des alternatives ?

    Par rapport aux solutions principales telles que next-intl ou i18next, Intlayer est une solution dotée d'optimisations intégrées telles que :

    Intlayer est optimisé pour fonctionner avec les composants serveur pour un rendu efficace et est entièrement compatible avec Turbopack. Il ne bloque pas le rendu statique et propose un middleware ainsi que toutes les fonctionnalités nécessaires à l'internationalisation à l'échelle (i18n).

    Intlayer est compatible avec Next.js 12, 13, 14, 15 et 16. Si vous utilisez le routeur de pages Next.js, vous pouvez vous référer à ce guide. Le routage local est utile pour le référencement, la taille du bundle et les performances. Si vous n'en avez pas besoin, vous pouvez vous référer à ce guide. Pour Next.js 12, 13, 14 et 15 avec App Router, reportez-vous à ce guide.

    Au lieu de charger de lourds fichiers JSON dans vos pages, ne chargez que le contenu strictement nécessaire. Intlayer vous aide à réduire la taille de votre bundle et de vos pages jusqu'à 50 %.

    Déclarer le contenu directement au plus près de vos composants facilite la maintenance des applications de grande envergure. Vous pouvez dupliquer ou supprimer le dossier d'une fonctionnalité sans le fardeau mental de devoir passer en revue toute votre base de code de contenu. De plus, Intlayer est entièrement typé pour garantir l'exactitude de vos traductions.

    La colocalisation du contenu réduit le contexte nécessaire aux grands modèles de langage (LLM). Intlayer est également livré avec une suite d'outils, tels qu'une CLI pour vérifier les traductions manquantes, un LSP, un MCP et des agent skills, afin de rendre l'expérience développeur (DX) encore plus fluide pour les agents IA.

    Automatisez les traductions dans votre pipeline CI/CD en utilisant le LLM de votre choix au coût de votre propre fournisseur d'IA. Intlayer propose également un compilateur pour automatiser l'extraction de contenu, ainsi qu'une plateforme web pour vous aider à traduire en arrière-plan.

    Associer de gros fichiers JSON à vos composants peut ralentir les performances et impacter la réactivité. Intlayer optimise le chargement du contenu directement au moment du build.

    Bien plus qu'une simple solution i18n, Intlayer propose un éditeur visuel auto-hébergé et un CMS complet pour gérer votre contenu multilingue en temps réel. Cela rend la collaboration avec les traducteurs, concepteurs-rédacteurs et autres membres de l'équipe extrêmement simple. Le contenu peut être stocké localement et/ou à distance.


    Guide étape par étape pour configurer Intlayer dans une application Next.js

    1. Installer les dépendances

      Installez les packages nécessaires en utilisant npm :

      bash
      npm install intlayer next-intlayernpx intlayer init
      • intlayer

        Le package principal qui fournit des outils d'internationalisation pour la gestion de la configuration, la traduction, la déclaration de contenu, la transpilation, et les commandes CLI.

      • next-intlayer

      Le package qui intègre Intlayer à Next.js. Il fournit des providers de contexte et des hooks pour l'internationalisation sous Next.js. De plus, il inclut le plugin Next.js pour intégrer Intlayer avec Webpack ou Turbopack, ainsi qu'un proxy pour détecter la locale préférée de l'utilisateur, gérer les cookies et gérer les redirections d'URL.

    2. Configurez votre projet

      Voici la structure finale que nous allons créer :

      bash
      .├── src│   ├── app│   │   ├── layout.tsx│   │   ├── page.content.ts│   │   └── page.tsx│   ├── components│   │   ├── clientComponentExample│   │   │   ├── client-component-example.content.ts│   │   │   └── ClientComponentExample.tsx│   │   ├── localeSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   └── serverComponentExample│   │       ├── server-component-example.content.ts│   │       └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
      Si vous ne voulez pas de routage par locale, intlayer peut être utilisé comme simple provider / hook. Voir ce guide pour plus de détails.

      Créez un fichier de configuration pour définir les langues de votre application :

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [
            Locales.ENGLISH,
            Locales.FRENCH,
            Locales.SPANISH,
            // Vos autres locales
          ],
          defaultLocale: Locales.ENGLISH,
        },
        routing: {
          mode: "search-params", // ou `no-prefix` - Utile pour la détection par le middleware
        },
      };
      
      export default config;
      Grâce à ce fichier de configuration, vous pouvez configurer les URL localisées, la redirection proxy, les noms des cookies, l'emplacement et l'extension de vos déclarations de contenu, désactiver les logs d'Intlayer dans la console, et plus encore. Pour la liste complète des paramètres disponibles, consultez la documentation de configuration.
    3. Intégrer Intlayer dans votre configuration Next.js

      Configurez votre setup Next.js pour utiliser Intlayer :

      next.config.ts
      import type { NextConfig } from "next";
      import { withIntlayer } from "next-intlayer/server";
      
      const nextConfig: NextConfig = {
        /* options de configuration ici */
      };
      
      export default withIntlayer(nextConfig);

      Le plugin Next.js withIntlayer() est utilisé pour intégrer Intlayer à Next.js. Il assure la génération des fichiers de déclaration de contenu et les surveille en mode développement. Il définit les variables d'environnement d'Intlayer dans les environnements Webpack ou Turbopack. De plus, il fournit des alias pour optimiser les performances et garantit la compatibilité avec les server components.

      La fonction withIntlayer() est une fonction retournant une Promise. Elle permet de préparer les dictionnaires Intlayer avant le démarrage de la build. Si vous souhaitez l'utiliser avec d'autres plugins, vous pouvez l'awaiter. Exemple:

      ts
      const nextConfig = await withIntlayer(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

      Si vous souhaitez l'utiliser de manière synchrone, vous pouvez utiliser la fonction withIntlayerSync(). Exemple :

      ts
      const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

      Intlayer détecte automatiquement si votre projet utilise webpack ou Turbopack en se basant sur les options de ligne de commande --webpack, --turbo ou --turbopack, ainsi que sur votre version de Next.js.

      Depuis next>=16, si vous utilisez Rspack, vous devez explicitement forcer Intlayer à utiliser la configuration webpack en désactivant Turbopack :

      ts
      withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));
    4. Définir des routes locales dynamiques

      Retirez tout le contenu de RootLayout et remplacez-le par le code suivant :

      src/app/layout.tsx
      import type { Metadata } from "next";
      import type { ReactNode } from "react";
      import "./globals.css";
      import { IntlayerClientProvider, LocalPromiseParams } from "next-intlayer";
      import { getHTMLTextDir, getIntlayer } from "intlayer";
      import { getLocale } from "next-intlayer/server";
      export { generateStaticParams } from "next-intlayer";
      
      export const generateMetadata = async (): Promise<Metadata> => {
        const locale = await getLocale();
        const { title, description, keywords } = getIntlayer("metadata", locale);
      
        return {
          title,
          description,
          keywords,
        };
      };
      
      const RootLayout = async ({
        children,
      }: Readonly<{
        children: ReactNode;
      }>) => {
        const locale = await getLocale();
      
        return (
          <html lang={locale} dir={getHTMLTextDir(locale)}>
            <IntlayerClientProvider defaultLocale={locale}>
              <body>{children}</body>
            </IntlayerClientProvider>
          </html>
        );
      };
      
      export default RootLayout;
    5. Déclarez votre contenu

      Créez et gérez vos déclarations de contenu pour stocker les traductions :

      src/app/metadata.content.ts
      import { t, type Dictionary } from "intlayer";
      import { Metadata } from "next";
      
      const metadataContent = {
        key: "metadata",
        content: {
          title: t({
            fr: "Le titre de mon projet",
            en: "My Project Title",
            es: "El Título de mi Proyecto",
          }),
      
          description: t({
            en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",
            fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",
            es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",
          }),
      
          keywords: t({
            fr: ["innovation", "productivité", "flux de travail", "SaaS"],
            en: ["innovation", "productivity", "workflow", "SaaS"],
            es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],
          }),
        },
      } as Dictionary<Metadata>;
      
      export default metadataContent;
      src/app/page.content.ts
      import { t, type Dictionary } from "intlayer";
      
      const pageContent = {
        key: "page",
        content: {
          getStarted: {
            main: t({
              fr: "Commencez par éditer",
              en: "Get started by editing",
              es: "Comience por editar",
            }),
            pageLink: "src/app/page.tsx",
          },
        },
      } satisfies Dictionary;
      
      export default pageContent;
      Vos déclarations de contenu peuvent être définies n'importe où dans votre application dès 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.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Pour plus de détails, consultez la documentation sur les déclarations de contenu.
    6. Utiliser le contenu dans votre code

      Accédez à vos dictionnaires de contenu partout dans votre application :

      src/app/page.tsx
      import type { FC } from "react";
      import { ClientComponentExample } from "@components/clientComponentExample/ClientComponentExample";
      import { ServerComponentExample } from "@components/serverComponentExample/ServerComponentExample";
      import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
      import { NextPage } from "next";
      import { getLocale } from "intlayer";
      import { headers, cookies } from "next/headers";
      
      const PageContent: FC = () => {
        const content = useIntlayer("page");
      
        return (
          <>
            <p>{content.getStarted.main}</p>
            <code>{content.getStarted.pageLink}</code>
          </>
        );
      };
      
      const Page: NextPage = async () => {
        // Attendre les en-têtes et les cookies dans Next.js 15+
        const headerList = await headers();
        const cookieList = await cookies();
      
        const locale = await getLocale({
          // Vérifier d'abord le cookie intlayer (par défaut : 'INTLAYER_LOCALE')
          getCookie: (name) => cookieList.get(name)?.value,
      
          // Ensuite vérifier l'en-tête intlayer (par défaut : 'x-intlayer-locale')
          // Et enfin vérifier l'en-tête accept-language ('accept-language')
          getHeader: (name) => headerList.get(name),
        });
      
        return (
          <IntlayerServerProvider locale={locale}>
            <PageContent />
            <ServerComponentExample />
            <ClientComponentExample />
          </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 des layouts entre les pages, ce qui le rend plus efficace. En utilisant IntlayerClientProvider dans le layout, vous évitez de le réinitialiser pour chaque page, améliorez les performances et maintenez un contexte de localisation cohérent dans toute votre application.
      • IntlayerServerProvider est utilisé pour fournir la locale aux enfants côté serveur. Il ne peut pas être défini dans le layout.
      Le layout et la page ne peuvent pas partager un même contexte serveur, car le système de contextes serveur est basé sur un magasin de données par requête (via le mécanisme le cache de React), ce qui fait que chaque "contexte" est recréé pour différents segments de l'application. Placer le provider dans un layout partagé briserait cette isolation, empêchant la bonne propagation des valeurs du contexte serveur vers vos composants serveur.
      src/components/clientComponentExample/ClientComponentExample.tsx
      "use client";
      
      import type { FC } from "react";
      import { useIntlayer } from "next-intlayer";
      
      export const ClientComponentExample: FC = () => {
        const content = useIntlayer("client-component-example"); // Créer la déclaration de contenu associée
      
        return (
          <div>
            <h2>{content.title}</h2>
            <p>{content.content}</p>
          </div>
        );
      };
      src/components/serverComponentExample/ServerComponentExample.tsx
      import type { FC } from "react";
      import { useIntlayer } from "next-intlayer/server";
      
      export const ServerComponentExample: FC = () => {
        const content = useIntlayer("server-component-example"); // Crée la 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 de type string, tel que alt, title, href, aria-label, etc., vous pouvez utiliser la valeur de la fonction, par exemple :
      html
      <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />
      Pour en savoir plus sur le hook useIntlayer, consultez la documentation.
    7. Configurer le proxy pour la détection de la locale

      Facultatif

      Configurez le proxy pour détecter la locale préférée de l'utilisateur :

      src/proxy.ts
      export { intlayerProxy as proxy } from "next-intlayer/proxy";
      
      export const config = {
        matcher:
          "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
      };
      Le intlayerProxy sert à détecter la locale préférée de l'utilisateur et à le rediriger vers l'URL appropriée, comme indiqué dans la configuration. De plus, il permet d'enregistrer la locale préférée de l'utilisateur dans un cookie.
      Si vous devez chaîner plusieurs proxies (par exemple intlayerProxy avec une authentification ou des proxies personnalisés), Intlayer fournit désormais un helper appelé multipleProxies.
      ts
      import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);
    8. Changer la langue de votre contenu

      Facultatif

      Pour changer la langue de votre contenu dans Next.js, la méthode recommandée est d'utiliser le composant Link pour rediriger les utilisateurs vers la page localisée appropriée. Le composant Link permet le préchargement (prefetch) de la page, ce qui aide à éviter un rechargement complet de la page.

      src/components/localeSwitcher/LocaleSwitcher.tsx
      "use client";
      
      import type { FC } from "react";
      import { Locales, getHTMLTextDir, getLocaleName } from "intlayer";
      import { useLocale } from "next-intlayer";
      
      export const LocaleSwitcher: FC = () => {
        const { locale, availableLocales, setLocale } = useLocale();
      
        return (
          <div>
            <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
            <div id="localePopover" popover="auto">
              {availableLocales.map((localeItem) => (
                <button
                  key={localeItem}
                  aria-current={locale === localeItem ? "page" : undefined}
                  onClick={() => setLocale(localeItem)}
                >
                  <span>
                    {/* Locale - ex. FR */}
                    {localeItem}
                  </span>
                  <span>
                    {/* Langue dans sa propre Locale - ex. Français */}
                    {getLocaleName(localeItem, locale)}
                  </span>
                  <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
                    {/* Langue dans la locale courante - ex. "Francés" lorsque la locale courante est Locales.SPANISH */}
                    {getLocaleName(localeItem)}
                  </span>
                  <span dir="ltr" lang={Locales.ENGLISH}>
                    {/* Langue en anglais - p.ex. French */}
                    {getLocaleName(localeItem, Locales.ENGLISH)}
                  </span>
                </button>
              ))}
            </div>
          </div>
        );
      };
      Une autre façon est d'utiliser la fonction setLocale fournie par le hook useLocale. Cette fonction n'autorisera pas le préchargement de la page. Consultez la documentation du hook useLocale pour plus de détails.

      Références de la documentation :

    9. Obtenir la locale courante dans les Server Actions

      Facultatif

      Si vous avez besoin de la locale active à l'intérieur d'une Server Action (par ex., pour localiser des e-mails ou exécuter une logique dépendante de la locale), appelez getLocale depuis next-intlayer/server :

      src/app/actions/getLocale.ts
      "use server";import { getLocale } from "next-intlayer/server";export const myServerAction = async () => {  const locale = await getLocale();  // Faire quelque chose avec la locale};

      La fonction getLocale suit une stratégie en cascade pour déterminer la locale de l'utilisateur :

      1. D'abord, elle vérifie les en-têtes de la requête pour une valeur de locale qui peut avoir été définie par le proxy
      2. Si aucune locale n'est trouvée dans les en-têtes, elle recherche une locale stockée dans les cookies
      3. Si aucun cookie n'est trouvé, elle tente de détecter la langue préférée de l'utilisateur à partir des paramètres du navigateur
      4. En dernier recours, elle revient à la locale par défaut configurée de l'application

      Cela garantit que la locale la plus appropriée est sélectionnée en fonction du contexte disponible.

    10. Optimisez la taille de votre bundle

      Facultatif

      Lors de l'utilisation de next-intlayer, les dictionnaires sont inclus dans le bundle pour chaque page par défaut. Pour optimiser la taille du bundle, Intlayer fournit un plugin SWC optionnel qui remplace intelligemment les appels à useIntlayer en utilisant des macros. Cela garantit que les dictionnaires ne sont inclus que dans les bundles des pages qui les utilisent réellement.

      Pour activer cette optimisation, installez le paquet @intlayer/swc. Une fois installé, next-intlayer détectera et utilisera automatiquement le plugin :

      bash
      npm install @intlayer/swc --save-dev
      Remarque : Cette optimisation n'est disponible que pour Next.js 13 et versions supérieures.
      Remarque : Ce package n'est pas installé par défaut car les plugins SWC sont encore expérimentaux sur Next.js. Cela peut changer à l'avenir.

      Remarque : Si vous définissez l'option sur importMode: 'dynamic' ou importMode: 'fetch' (dans la configuration dictionary), cela reposera sur Suspense, vous devrez donc envelopper vos appels useIntlayer dans une frontière Suspense. Cela signifie que vous ne pourrez pas utiliser useIntlayer directement au niveau supérieur de votre composant Page / Layout.

    Surveiller les modifications des dictionnaires sur Turbopack

    Lorsque vous utilisez Turbopack comme serveur de développement avec la commande next dev, les modifications du dictionnaire ne seront pas détectées automatiquement par défaut.

    Cette limitation survient parce que Turbopack ne peut pas exécuter les plugins webpack en parallèle pour surveiller les changements de vos fichiers de contenu. Pour contourner cela, vous devrez utiliser la commande intlayer watch afin d'exécuter simultanément le serveur de développement et le watcher de build d'Intlayer.

    package.json
    {  // ... Vos configurations existantes de package.json  "scripts": {    // ... Vos configurations de scripts existantes    "dev": "intlayer watch --with 'next dev'",  },}
    Si vous utilisez next-intlayer@<=6.x.x, vous devez conserver le flag --turbopack pour que l'application Next.js 16 fonctionne correctement avec Turbopack. Nous recommandons d'utiliser next-intlayer@>=7.x.x pour éviter cette limitation.

    Configurer TypeScript

    Intlayer utilise le module augmentation pour bénéficier des avantages de TypeScript et renforcer votre codebase.

    Autocompletion

    Translation error

    Assurez-vous que votre configuration TypeScript inclut les types générés automatiquement.

    tsconfig.json
    {  // ... Vos configurations TypeScript existantes  "include": [    // ... Vos configurations TypeScript existantes    ".intlayer/**/*.ts", // Inclure les types générés automatiquement  ],}

    Configuration Git

    Il est recommandé d'ignorer les fichiers générés par Intlayer. Cela vous permet d'éviter de les inclure dans votre dépôt Git.

    Pour cela, vous pouvez ajouter les instructions suivantes à votre fichier .gitignore :

    .gitignore
    # Ignorer les fichiers générés par Intlayer.intlayer

    Extension VS Code

    Pour améliorer votre expérience de développement avec Intlayer, vous pouvez installer l'extension officielle Intlayer VS Code Extension.

    Installer depuis le Marketplace VS Code

    Cette extension offre :

    • Autocomplétion pour les clés de traduction.
    • Détection d'erreurs en temps réel pour les traductions manquantes.
    • Aperçus intégrés du contenu traduit.
    • Actions rapides pour créer et mettre à jour facilement les traductions.

    Pour plus de détails sur l'utilisation de l'extension, consultez la documentation de l'extension VS Code Intlayer.

    Aller plus loin

    Pour aller plus loin, vous pouvez implémenter l'éditeur visuel ou externaliser votre contenu en utilisant le CMS.