IntlPull
Tutorial
25 min read

next-intl : Le Guide Complet de l'Internationalisation Next.js (2026)

Maîtrisez next-intl pour Next.js App Router. Tutoriel complet couvrant la configuration, le routage, les Server Components, le formatage, TypeScript et les meilleures pratiques de production.

IntlPull Team
IntlPull Team
03 Feb 2026, 11:44 AM [PST]
On this page
Summary

Maîtrisez next-intl pour Next.js App Router. Tutoriel complet couvrant la configuration, le routage, les Server Components, le formatage, TypeScript et les meilleures pratiques de production.

Réponse Rapide

next-intl est la meilleure bibliothèque d'internationalisation (i18n) pour Next.js App Router. Installez avec npm install next-intl, créez un dossier [locale] dans votre répertoire app, configurez le middleware pour la détection de locale, et utilisez getTranslations() dans les Server Components ou useTranslations() dans les Client Components. next-intl est spécifiquement conçu pour Next.js 13-15+ avec un support natif des Server Components, un routage automatique et une taille de bundle de ~2KB.


Qu'est-ce que next-intl ?

next-intl est une bibliothèque d'internationalisation légère construite spécifiquement pour Next.js. Contrairement aux bibliothèques i18n React généralistes, next-intl a été conçu dès le départ pour l'App Router et les Server Components.

Pourquoi next-intl Plutôt que d'Autres Bibliothèques ?

Fonctionnaliténext-intlreact-i18nextreact-intl
Construit pour Next.jsOuiNon (Général React)Non (Général React)
Server ComponentsNatifNécessite un wrapperNécessite un wrapper
Taille du bundle~2KB~8KB~12KB
Support App RouterDe premier ordrePartielPartiel
TypeScriptExcellentBonBon
Intégration routageIntégréManuelManuel

Avantages clés :

  • Zéro JS côté client pour les traductions rendues par le serveur - les traductions restent sur le serveur
  • Routage locale automatique - /en/about, /fr/about gérés automatiquement
  • Format de message ICU - pluralisation, genre et formatage corrects
  • Type-safe - support TypeScript complet avec autocomplétion

Lorsque vous passez à plus grande échelle que les fichiers JSON, IntlPull s'intègre parfaitement avec next-intl pour la gestion de traduction, la traduction IA et la collaboration d'équipe.


Installation & Configuration

Étape 1 : Installer next-intl

Terminal
1npm install next-intl
2# ou
3yarn add next-intl
4# ou
5pnpm add next-intl

Étape 2 : Structure du Projet

Créez cette structure de dossier :

/votre-app-nextjs
├── /app
│   └── /[locale]           # Segment locale dynamique
│       ├── layout.tsx      # Layout conscient de la locale
│       ├── page.tsx        # Page d'accueil
│       └── /about
│           └── page.tsx    # Page à propos
├── /messages               # Fichiers de traduction
│   ├── en.json
│   ├── es.json
│   └── de.json
├── /i18n
│   ├── config.ts           # Configuration locale
│   └── request.ts          # Config côté serveur
├── middleware.ts           # Détection locale & routage
└── next.config.js

Étape 3 : Configurer les Locales

Créez i18n/config.ts:

TypeScript
1export const locales = ['en', 'es', 'de', 'fr', 'ja'] as const;
2export type Locale = (typeof locales)[number];
3export const defaultLocale: Locale = 'en';
4
5// Optionnel : métadonnées locale pour UI
6export const localeNames: Record<Locale, string> = {
7  en: 'English',
8  es: 'Español',
9  de: 'Deutsch',
10  fr: 'Français',
11  ja: '日本語',
12};

Étape 4 : Créer la Configuration de Requête

Créez i18n/request.ts:

TypeScript
1import { getRequestConfig } from 'next-intl/server';
2import { notFound } from 'next/navigation';
3import { locales } from './config';
4
5export default getRequestConfig(async ({ locale }) => {
6  // Valider que la locale entrante est supportée
7  if (!locales.includes(locale as any)) {
8    notFound();
9  }
10
11  return {
12    messages: (await import(`../messages/${locale}.json`)).default,
13  };
14});

Étape 5 : Configurer next.config.js

JavaScript
1const createNextIntlPlugin = require('next-intl/plugin');
2
3const withNextIntl = createNextIntlPlugin('./i18n/request.ts');
4
5/** @type {import('next').NextConfig} */
6const nextConfig = {
7  // Votre autre config Next.js
8};
9
10module.exports = withNextIntl(nextConfig);

Étape 6 : Créer le Middleware

Créez middleware.ts à la racine de votre projet :

TypeScript
1import createMiddleware from 'next-intl/middleware';
2import { locales, defaultLocale } from './i18n/config';
3
4export default createMiddleware({
5  locales,
6  defaultLocale,
7  localePrefix: 'always', // ou 'as-needed' ou 'never'
8});
9
10export const config = {
11  // Correspondre à tous les chemins sauf
12  // - Routes API
13  // - _next (internes Next.js)
14  // - Fichiers statiques (images, etc.)
15  matcher: ['/((?!api|_next|.*\\..*).*)'],
16};

Étape 7 : Créer les Fichiers de Traduction

Créez messages/en.json:

JSON
1{
2  "common": {
3    "welcome": "Welcome to our app",
4    "loading": "Loading...",
5    "error": "Something went wrong"
6  },
7  "home": {
8    "title": "Home",
9    "description": "This is the home page",
10    "cta": "Get Started"
11  },
12  "navigation": {
13    "home": "Home",
14    "about": "About",
15    "contact": "Contact"
16  }
17}

Créez messages/fr.json:

JSON
1{
2  "common": {
3    "welcome": "Bienvenue sur notre application",
4    "loading": "Chargement...",
5    "error": "Une erreur est survenue"
6  },
7  "home": {
8    "title": "Accueil",
9    "description": "Ceci est la page d'accueil",
10    "cta": "Commencer"
11  },
12  "navigation": {
13    "home": "Accueil",
14    "about": "À propos",
15    "contact": "Contact"
16  }
17}

Étape 8 : Créer le Layout Racine

Créez app/[locale]/layout.tsx:

TypeScript
1import { NextIntlClientProvider } from 'next-intl';
2import { getMessages } from 'next-intl/server';
3import { notFound } from 'next/navigation';
4import { locales } from '@/i18n/config';
5
6export function generateStaticParams() {
7  return locales.map((locale) => ({ locale }));
8}
9
10export default async function LocaleLayout({
11  children,
12  params: { locale },
13}: {
14  children: React.ReactNode;
15  params: { locale: string };
16}) {
17  // Valider la locale
18  if (!locales.includes(locale as any)) {
19    notFound();
20  }
21
22  // Obtenir les messages pour la locale actuelle
23  const messages = await getMessages();
24
25  return (
26    <html lang={locale}>
27      <body>
28        <NextIntlClientProvider messages={messages}>
29          {children}
30        </NextIntlClientProvider>
31      </body>
32    </html>
33  );
34}

Utiliser les Traductions

Server Components (Recommandé)

Dans les Server Components, utilisez getTranslations():

TypeScript
1import { getTranslations } from 'next-intl/server';
2
3export default async function HomePage() {
4  const t = await getTranslations('home');
5
6  return (
7    <main>
8      <h1>{t('title')}</h1>
9      <p>{t('description')}</p>
10      <button>{t('cta')}</button>
11    </main>
12  );
13}

C'est l'approche recommandée car :

  • Les traductions sont rendues sur le serveur
  • Zéro JavaScript envoyé au client pour ces chaînes
  • Meilleure performance et SEO

Client Components

Pour les composants interactifs, utilisez useTranslations():

TypeScript
1'use client';
2
3import { useTranslations } from 'next-intl';
4
5export function AddToCartButton() {
6  const t = useTranslations('product');
7
8  const handleClick = () => {
9    // Logique côté client
10  };
11
12  return (
13    <button onClick={handleClick}>
14      {t('addToCart')}
15    </button>
16  );
17}

Accéder à Plusieurs Espaces de Noms

TypeScript
1import { getTranslations } from 'next-intl/server';
2
3export default async function Page() {
4  const t = await getTranslations('home');
5  const tCommon = await getTranslations('common');
6
7  return (
8    <div>
9      <h1>{t('title')}</h1>
10      <p>{tCommon('welcome')}</p>
11    </div>
12  );
13}

Variables et Interpolation

Variables de Base

JSON
1{
2  "greeting": "Hello, {name}!",
3  "items": "You have {count} items in your cart"
4}
TypeScript
t('greeting', { name: 'John' })  // "Hello, John!"
t('items', { count: 5 })         // "You have 5 items in your cart"

Pluralisation (Format ICU)

next-intl utilise le format de message ICU pour une pluralisation correcte :

JSON
{
  "cartItems": "{count, plural, =0 {Your cart is empty} one {# item in cart} other {# items in cart}}"
}
TypeScript
t('cartItems', { count: 0 })   // "Your cart is empty"
t('cartItems', { count: 1 })   // "1 item in cart"
t('cartItems', { count: 5 })   // "5 items in cart"

Catégories plurielles ICU par langue :

LangueCatégories
Anglaisone, other
Françaisone, other (parfois many)
Russeone, few, many, other
Arabezero, one, two, few, many, other
Japonaisother (pas de pluriels)

next-intl gère tout cela automatiquement basé sur la locale.

Select (Genre, Statut, etc.)

JSON
{
  "userStatus": "{status, select, online {User is online} offline {User is offline} away {User is away} other {Unknown status}}"
}
TypeScript
t('userStatus', { status: 'online' })  // "User is online"

Texte Riche (HTML/Composants)

JSON
{
  "terms": "By signing up, you agree to our <terms>Terms of Service</terms> and <privacy>Privacy Policy</privacy>."
}
TypeScript
1import { useTranslations } from 'next-intl';
2import Link from 'next/link';
3
4function SignupForm() {
5  const t = useTranslations('auth');
6
7  return (
8    <p>
9      {t.rich('terms', {
10        terms: (chunks) => <Link href="/terms">{chunks}</Link>,
11        privacy: (chunks) => <Link href="/privacy">{chunks}</Link>,
12      })}
13    </p>
14  );
15}

Formatage Nombre, Date et Devise

Formatage de Nombre

TypeScript
1import { useFormatter } from 'next-intl';
2
3function PriceDisplay({ price }: { price: number }) {
4  const format = useFormatter();
5
6  return (
7    <span>
8      {format.number(price, { style: 'currency', currency: 'USD' })}
9    </span>
10  );
11}
12
13// en-US: "$1,234.56"
14// de-DE: "1.234,56 $"
15// ja-JP: "$1,234.56"

Formatage de Date

TypeScript
1import { useFormatter } from 'next-intl';
2
3function DateDisplay({ date }: { date: Date }) {
4  const format = useFormatter();
5
6  return (
7    <>
8      <p>{format.dateTime(date, { dateStyle: 'full' })}</p>
9      <p>{format.dateTime(date, { timeStyle: 'short' })}</p>
10      <p>{format.relativeTime(date)}</p>
11    </>
12  );
13}
14
15// en-US: "Friday, January 17, 2026"
16// de-DE: "Freitag, 17. Januar 2026"

Temps Relatif

TypeScript
1const format = useFormatter();
2
3format.relativeTime(new Date('2026-01-10'))  // "7 days ago"
4format.relativeTime(new Date('2026-01-20'))  // "in 3 days"

Formatage de Liste

TypeScript
1const format = useFormatter();
2
3format.list(['Apple', 'Banana', 'Orange'], { type: 'conjunction' })
4// en: "Apple, Banana, and Orange"
5// de: "Apple, Banana und Orange"

Routage et Navigation

Liens Conscients de la Locale

Utilisez next-intl/link pour le préfixage automatique de locale :

TypeScript
1import Link from 'next-intl/link';
2
3function Navigation() {
4  return (
5    <nav>
6      <Link href="/">Home</Link>
7      <Link href="/about">About</Link>
8      <Link href="/contact">Contact</Link>
9    </nav>
10  );
11}
12// Rends automatiquement comme /en/about, /fr/about basé sur la locale actuelle

useRouter Conscient de la Locale

TypeScript
1'use client';
2
3import { useRouter } from 'next-intl/client';
4
5function SearchForm() {
6  const router = useRouter();
7
8  const handleSearch = (query: string) => {
9    router.push(`/search?q=${query}`);
10    // Inclut automatiquement le préfixe locale
11  };
12
13  return (/* form */);
14}

Sélecteur de Langue

TypeScript
1'use client';
2
3import { useLocale } from 'next-intl';
4import { useRouter, usePathname } from 'next-intl/client';
5import { locales, localeNames } from '@/i18n/config';
6
7export function LanguageSwitcher() {
8  const locale = useLocale();
9  const router = useRouter();
10  const pathname = usePathname();
11
12  const handleChange = (newLocale: string) => {
13    router.replace(pathname, { locale: newLocale });
14  };
15
16  return (
17    <select value={locale} onChange={(e) => handleChange(e.target.value)}>
18      {locales.map((loc) => (
19        <option key={loc} value={loc}>
20          {localeNames[loc]}
21        </option>
22      ))}
23    </select>
24  );
25}

Stratégies d'URL

Configurez dans le middleware :

TypeScript
1// Option 1 : Toujours montrer le préfixe locale
2// /en/about, /es/about, /de/about
3localePrefix: 'always'
4
5// Option 2 : Cacher la locale par défaut
6// /about (Anglais), /es/about (Espagnol)
7localePrefix: 'as-needed'
8
9// Option 3 : Ne jamais montrer le préfixe (utiliser cookies/headers)
10localePrefix: 'never'

Recommandation : Utilisez 'always' pour le meilleur SEO et les URL les plus claires.


Intégration TypeScript

Traductions Type-Safe

Créez global.d.ts:

TypeScript
1import en from './messages/en.json';
2
3type Messages = typeof en;
4
5declare global {
6  interface IntlMessages extends Messages {}
7}

Maintenant vous obtenez l'autocomplétion et la vérification de type :

TypeScript
1const t = useTranslations('home');
2
3t('title')        // ✅ Valide
4t('nonExistent')  // ❌ Erreur TypeScript

Clés Imbriquées

TypeScript
// Pour les messages profondément imbriqués
const t = useTranslations('settings.account.privacy');
t('title')  // settings.account.privacy.title

SEO et Métadonnées

Métadonnées Conscientes de la Locale

TypeScript
1import { getTranslations } from 'next-intl/server';
2import { Metadata } from 'next';
3
4export async function generateMetadata({
5  params: { locale },
6}: {
7  params: { locale: string };
8}): Promise<Metadata> {
9  const t = await getTranslations({ locale, namespace: 'meta' });
10
11  return {
12    title: t('title'),
13    description: t('description'),
14  };
15}

Balises Hreflang

TypeScript
1import { locales } from '@/i18n/config';
2
3export async function generateMetadata({
4  params: { locale },
5}: {
6  params: { locale: string };
7}) {
8  const baseUrl = 'https://example.com';
9
10  return {
11    alternates: {
12      canonical: `${baseUrl}/${locale}`,
13      languages: Object.fromEntries(
14        locales.map((loc) => [loc, `${baseUrl}/${loc}`])
15      ),
16    },
17  };
18}

Cela génère des balises hreflang appropriées pour le SEO :

HTML
<link rel="alternate" hreflang="en" href="https://example.com/en" />
<link rel="alternate" hreflang="es" href="https://example.com/es" />
<link rel="alternate" hreflang="de" href="https://example.com/de" />

Optimisation de la Performance

Division de Code Basée sur l'Espace de Noms

Chargez seulement les traductions nécessaires pour chaque page :

TypeScript
1// Dans i18n/request.ts
2export default getRequestConfig(async ({ locale }) => {
3  return {
4    messages: {
5      // Charger seulement l'espace de noms commun par défaut
6      common: (await import(`../messages/${locale}/common.json`)).default,
7    },
8  };
9});
10
11// Dans les pages spécifiques, charger des espaces de noms supplémentaires
12import { getMessages } from 'next-intl/server';
13
14export default async function CheckoutPage() {
15  const messages = await getMessages({ namespace: 'checkout' });
16  // ...
17}

Génération Statique

Assurez-vous que toutes les pages locale sont générées statiquement :

TypeScript
export function generateStaticParams() {
  return locales.map((locale) => ({ locale }));
}

Éviter les Inadéquations d'Hydratation

Passez l'heure serveur pour éviter les inadéquations date/heure :

TypeScript
1<NextIntlClientProvider
2  messages={messages}
3  timeZone="Europe/Berlin"
4  now={new Date()}
5>
6  {children}
7</NextIntlClientProvider>

Gérer les Traductions à l'Échelle

À mesure que votre app grandit, gérer les fichiers JSON manuellement devient problématique :

  • Traductions manquantes difficiles à suivre
  • Conflits de fusion quand plusieurs développeurs éditent les fichiers de traduction
  • Pas de contexte pour les traducteurs
  • Flux lent avec export/import manuel

Intégration IntlPull

IntlPull fournit une intégration next-intl transparente :

Terminal
1# Initialiser IntlPull dans votre projet
2npx @intlpullhq/cli init
3
4# Télécharger vos traductions existantes (upload)
5npx @intlpullhq/cli upload
6
7# Obtenir des traductions IA pour de nouvelles langues
8npx @intlpullhq/cli translate --languages es,de,fr,ja
9
10# Tirer les traductions vers votre projet (download)
11npx @intlpullhq/cli download
12
13# Mode surveillance pour sync temps réel pendant le développement
14npx @intlpullhq/cli watch

Avantages :

  • Traduction alimentée par IA avec GPT-4, Claude, DeepL
  • Éditeur visuel avec contexte par capture d'écran
  • Collaboration d'équipe avec flux de révision
  • Sync automatique avec votre base de code
  • Mémoire de traduction pour la cohérence

Commencez gratuitement avec IntlPull →


Modèles Courants

États de Chargement avec Suspense

TypeScript
1import { Suspense } from 'react';
2
3export default function Page() {
4  return (
5    <Suspense fallback={<Skeleton />}>
6      <TranslatedContent />
7    </Suspense>
8  );
9}

Frontières d'Erreur (Error Boundaries)

TypeScript
1import { useTranslations } from 'next-intl';
2
3function ErrorBoundary({ error }: { error: Error }) {
4  const t = useTranslations('errors');
5
6  return (
7    <div>
8      <h2>{t('title')}</h2>
9      <p>{t('message')}</p>
10    </div>
11  );
12}

Routes Dynamiques avec Locales

TypeScript
1// app/[locale]/blog/[slug]/page.tsx
2import { getTranslations } from 'next-intl/server';
3
4export default async function BlogPost({
5  params: { locale, slug },
6}: {
7  params: { locale: string; slug: string };
8}) {
9  const t = await getTranslations('blog');
10
11  // Récupérer le contenu localisé
12  const post = await getPost(slug, locale);
13
14  return (
15    <article>
16      <h1>{post.title}</h1>
17      <p>{t('readTime', { minutes: post.readTime })}</p>
18    </article>
19  );
20}

Support Langue RTL

Pour l'Arabe, l'Hébreu, le Persan et autres langues RTL :

TypeScript
1import { locales } from '@/i18n/config';
2
3const rtlLocales = ['ar', 'he', 'fa'];
4
5export default async function LocaleLayout({
6  children,
7  params: { locale },
8}: {
9  children: React.ReactNode;
10  params: { locale: string };
11}) {
12  const dir = rtlLocales.includes(locale) ? 'rtl' : 'ltr';
13
14  return (
15    <html lang={locale} dir={dir}>
16      <body>{children}</body>
17    </html>
18  );
19}

Utilisez les propriétés logiques CSS :

CSS
1/* Au lieu de margin-left, utilisez : */
2margin-inline-start: 1rem;
3
4/* Au lieu de padding-right, utilisez : */
5padding-inline-end: 1rem;
6
7/* Au lieu de text-align: left, utilisez : */
8text-align: start;

Tests

Tests Unitaires de Composants

TypeScript
1import { render, screen } from '@testing-library/react';
2import { NextIntlClientProvider } from 'next-intl';
3import messages from '../messages/en.json';
4import { HomePage } from './page';
5
6function renderWithIntl(ui: React.ReactNode, locale = 'en') {
7  return render(
8    <NextIntlClientProvider locale={locale} messages={messages}>
9      {ui}
10    </NextIntlClientProvider>
11  );
12}
13
14test('renders home page title', () => {
15  renderWithIntl(<HomePage />);
16  expect(screen.getByText('Home')).toBeInTheDocument();
17});

Tester Plusieurs Locales

TypeScript
1const locales = ['en', 'es', 'de'];
2
3describe.each(locales)('HomePage in %s', (locale) => {
4  test('renders without crashing', () => {
5    const messages = require(`../messages/${locale}.json`);
6    renderWithIntl(<HomePage />, locale, messages);
7    // Affirmer basé sur les traductions attendues
8  });
9});

Migrer vers next-intl

Depuis react-i18next

TypeScript
1// Avant (react-i18next)
2import { useTranslation } from 'react-i18next';
3const { t } = useTranslation();
4t('home.title')
5
6// Après (next-intl)
7import { useTranslations } from 'next-intl';
8const t = useTranslations('home');
9t('title')

Depuis next-translate

TypeScript
1// Avant (next-translate)
2import useTranslation from 'next-translate/useTranslation';
3const { t } = useTranslation('common');
4
5// Après (next-intl)
6import { useTranslations } from 'next-intl';
7const t = useTranslations('common');

Le format de fichier de traduction est similaire — la plupart des fichiers JSON fonctionnent sans changement.


next-intl vs Alternatives

Aspectnext-intlreact-i18nextnext-translate
Optimisé Next.jsOuiNonOui
Server ComponentsNatifWrapper nécessaireNatif
Taille du bundle~2KB~8KB~1.5KB
Format ICUCompletPlugin nécessaireBasique
TypeScriptExcellentBonBasique
RoutageIntégréManuelIntégré
Développement actifTrès actifActifModéré
DocumentationExcellentBonBon

Recommandation : Utilisez next-intl pour tout nouveau projet Next.js App Router. C'est l'option la plus complète et la mieux maintenue spécifiquement conçue pour Next.js.


Dépannage

Erreurs "Missing message"

TypeScript
1// En développement, montrer le nom de la clé ; en production, retourner vide
2<NextIntlClientProvider
3  messages={messages}
4  onError={(error) => {
5    if (process.env.NODE_ENV === 'development') {
6      console.error(error);
7    }
8  }}
9  getMessageFallback={({ key }) => {
10    return process.env.NODE_ENV === 'development' ? `[${key}]` : '';
11  }}
12>

Inadéquation d'Hydratation

Généralement causée par des différences de date/heure entre serveur et client :

TypeScript
1// Passer l'heure serveur explicitement
2<NextIntlClientProvider
3  messages={messages}
4  now={new Date()}
5  timeZone="UTC"
6>

Middleware Ne S'exécutant Pas

Vérifiez votre modèle matcher :

TypeScript
1export const config = {
2  matcher: [
3    // Correspondre à tous les chemins sauf fichiers statiques et API
4    '/((?!api|_next/static|_next/image|favicon.ico|.*\\..*).*)',
5  ],
6};

Foire Aux Questions

Qu'est-ce que next-intl ?

next-intl est une bibliothèque d'internationalisation (i18n) spécifiquement construite pour Next.js. Elle fournit la gestion de traduction, le routage basé sur la locale, le formatage date/nombre, et un support complet pour les Server Components et l'App Router. C'est la solution i18n recommandée pour les projets Next.js 13+ en raison de son intégration native et de sa petite taille de bundle (~2KB).

next-intl est-il meilleur que react-i18next pour Next.js ?

Oui, next-intl est meilleur que react-i18next pour les projets Next.js App Router. next-intl a été conçu spécifiquement pour Next.js avec un support natif des Server Components, un routage intégré, et zéro configuration pour l'App Router. react-i18next est une bibliothèque React générale qui nécessite une configuration supplémentaire pour les Server Components et ne s'intègre pas aussi parfaitement avec le routage Next.js.

Comment configurer next-intl avec Next.js App Router ?

Pour configurer next-intl : (1) Installez avec npm install next-intl, (2) Créez un dossier [locale] dans le répertoire app, (3) Créez des fichiers JSON de traduction dans un dossier messages, (4) Configurez middleware.ts pour la détection locale, (5) Créez i18n/request.ts pour la config serveur, (6) Enveloppez votre app avec NextIntlClientProvider. Voir la section configuration complète ci-dessus pour le code détaillé.

next-intl fonctionne-t-il avec les Server Components ?

Oui, next-intl a un support natif des Server Components. Utilisez getTranslations() de next-intl/server dans les Server Components — les traductions sont rendues sur le serveur avec zéro JavaScript côté client. C'est un avantage majeur par rapport à react-i18next qui nécessite des composants wrapper pour le support Server Component.

Comment ajouter un sélecteur de langue avec next-intl ?

Utilisez useLocale() et useRouter() de next-intl : Obtenez la locale actuelle avec useLocale(), obtenez le chemin avec usePathname() de next-intl/client, puis appelez router.replace(pathname, { locale: newLocale }) pour changer de langue. Voir la section Sélecteur de Langue ci-dessus pour le code complet.

Comment gérer la pluralisation dans next-intl ?

next-intl utilise le format de message ICU pour la pluralisation. Définissez les messages pluriels comme : "{count, plural, =0 {No items} one {# item} other {# items}}". Puis appelez t('key', { count: 5 }). next-intl sélectionne automatiquement la forme plurielle correcte basée sur la locale — gérant les langues avec 2 formes (Anglais) jusqu'à 6 formes (Arabe) correctement.

Puis-je utiliser next-intl avec TypeScript ?

Oui, next-intl a un excellent support TypeScript. Créez un fichier global.d.ts qui étend IntlMessages avec vos types de messages, et vous obtiendrez l'autocomplétion complète et la vérification de type pour les clés de traduction. Cela attrape les clés manquantes ou mal orthographiées à la compilation plutôt qu'à l'exécution.

Comment gérer les traductions à l'échelle avec next-intl ?

Utilisez un Système de Gestion de Traduction (TMS) comme IntlPull quand vous avez 500+ chaînes ou 3+ langues. IntlPull fournit : sync CLI (npx @intlpullhq/cli upload/download), traduction alimentée par IA, collaboration d'équipe, contexte visuel pour traducteurs, et intégration next-intl transparente. Cela élimine la gestion manuelle de fichiers JSON et les conflits de fusion.

Quelle est la taille du bundle de next-intl ?

next-intl ajoute environ 2KB à votre bundle client (gzippé). C'est significativement plus petit que react-i18next (~8KB) ou react-intl (~12KB). De plus, les traductions rendues dans les Server Components ajoutent zéro octet au bundle client puisqu'elles sont rendues côté serveur.

next-intl supporte-t-il les langues RTL ?

Oui, next-intl supporte pleinement les langues RTL comme l'Arabe, l'Hébreu et le Persan. Vous devez définir l'attribut dir="rtl" sur votre élément HTML basé sur la locale et utiliser les propriétés logiques CSS (margin-inline-start au lieu de margin-left). Voir la section Support Langue RTL pour les détails d'implémentation.

Comment tester les composants utilisant next-intl ?

Enveloppez les composants avec NextIntlClientProvider dans les tests. Créez une fonction d'aide qui enveloppe votre composant avec le provider, la locale et les messages. Utilisez cela pour les tests unitaires et les tests d'intégration. Vous pouvez tester plusieurs locales en utilisant describe.each() pour assurer que les traductions fonctionnent dans toutes les langues supportées.


Résumé

next-intl est le meilleur choix pour l'internationalisation Next.js en 2026. Points clés à retenir :

  1. Construit pour Next.js - Support natif App Router et Server Component
  2. Léger - Bundle ~2KB, zéro JS pour les traductions rendues serveur
  3. Complet - Routage, formatage, pluralisation, TypeScript
  4. Bien maintenu - Développement actif, documentation excellente

Pour commencer :

  1. npm install next-intl
  2. Créez la structure de dossier [locale]
  3. Configurez middleware et i18n/request.ts
  4. Utilisez getTranslations() dans les Server Components
  5. Passez à l'échelle avec IntlPull pour la traduction IA et la collaboration d'équipe

Prêt à gérer les traductions next-intl professionnellement ? Commencez gratuitement avec IntlPull — traduction IA, éditeur visuel, et sync CLI inclus.

Tags
next-intl
nextjs
i18n
internationalization
app-router
server-components
react
2026
IntlPull Team
IntlPull Team
Engineering

Building tools to help teams ship products globally. Follow us for more insights on localization and i18n.