next-intl 4
Cette compétence couvre next-intl 4.x tel que documenté sur https://next-intl.dev/docs/getting-started (docs version 4.14.9). Elle met en évidence ce qui diffère des habitudes : valeurs par défaut surprenantes, pièges, API héritées et motifs recommandés par la documentation. Chaque affirmation dans les fichiers de référence se termine par la page dont elle est extraite.
Comment naviguer
- Lisez le démarrage rapide et les règles rapides ci-dessous. Ils couvrent les erreurs les plus fréquentes.
- Ouvrez le fichier de référence correspondant à la tâche, depuis le tableau en fin de document.
- Lorsque le code utilise
setRequestLocale,requestLocaleoumiddleware.ts, lisez d'abord le tableau "Anciens motifs".
Démarrage rapide (App Router)
Le App Router est la voie recommandée. Le Pages Router reste supporté, voir references/setup.md. https://next-intl.dev/docs/getting-started/pages-router
// next.config.ts
import {NextConfig} from 'next';
import createNextIntlPlugin from 'next-intl/plugin';
const nextConfig: NextConfig = {};
const withNextIntl = createNextIntlPlugin();
export default withNextIntl(nextConfig);
https://next-intl.dev/docs/getting-started/app-router
Sans URLs basées sur la locale, src/i18n/request.ts résout la locale à partir d'une préférence utilisateur, au plus simple un cookie :
// src/i18n/request.ts
import {cookies} from 'next/headers';
import {getRequestConfig} from 'next-intl/server';
export default getRequestConfig(async () => {
const store = await cookies();
const locale = store.get('locale')?.value || 'en';
return {
locale,
messages: (await import(`../../messages/${locale}.json`)).default
};
});
https://next-intl.dev/docs/getting-started/app-router
// src/app/layout.tsx
import {NextIntlClientProvider} from 'next-intl';
import {getLocale} from 'next-intl/server';
export default async function RootLayout({children}) {
const locale = await getLocale();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider>{children}</NextIntlClientProvider>
</body>
</html>
);
}
https://next-intl.dev/docs/getting-started/app-router , https://next-intl.dev/docs/usage/configuration
import {useTranslations} from 'next-intl';
import {getTranslations} from 'next-intl/server';
export function HomePage() {
const t = useTranslations('HomePage'); // composant non async
return <h1>{t('title')}</h1>;
}
export async function Profile() {
const t = await getTranslations('ProfilePage'); // composant async
return <h1>{t('title')}</h1>;
}
https://next-intl.dev/docs/getting-started/app-router
Pour des URLs de type /fr/a-propos, ajoutez src/i18n/routing.ts, src/proxy.ts, src/i18n/navigation.ts et un segment [locale] racine : references/routing.md. https://next-intl.dev/docs/routing/setup
Règles rapides
Configuration
- Le plugin cherche
i18n/request.tsdanssrc/ou à la racine du projet (.ts,.tsx,.js,.jsx). Ailleurs, passez le chemin :createNextIntlPlugin('./chemin/vers/request.ts'). https://next-intl.dev/docs/getting-started/app-router - L'exemple de la documentation utilise en dur
const locale = 'en'. Remplacez-le par une résolution réelle (cookie, préférence utilisateur ounext/root-params). https://next-intl.dev/docs/getting-started/app-router getRequestConfigs'exécute une fois par requête, lors du rendu des Server Components, donccookies()etheaders()fonctionnent ici. https://next-intl.dev/docs/usage/configuration- Définissez
timeZonedans la configuration de la requête. La valeur par défaut est le fuseau horaire de l'environnement d'exécution serveur. https://next-intl.dev/docs/usage/configuration
Routage
- Nommez le fichier
src/proxy.tssur Next.js 16. L'import restecreateMiddlewaredepuisnext-intl/middleware. https://next-intl.dev/docs/routing/setup - Lisez la locale avec
await rootParams.locale()depuisnext/root-params, validez-la avechasLocale(routing.locales, value), sinonnotFound(). Next.js avant 16.3 nécessiteexperimental.rootParams. https://next-intl.dev/docs/routing/setup - Importez
Link,redirect,usePathname,useRouteretgetPathnamedepuis votrei18n/navigation.tsau lieu denext/linkounext/navigation. https://next-intl.dev/docs/routing/navigation - Changez de locale avec
router.replace(pathname, {locale})depuis ce module.<Link locale>n'est pas préchargé, pour éviter d'écraser le cookie de locale. https://next-intl.dev/docs/routing/navigation redirectprend toujours une locale :redirect({href: '/login', locale}). Écrivezreturn redirect(...)pour que TypeScript réduise le type. https://next-intl.dev/docs/routing/navigation- Le matcher par défaut ignore les chemins contenant un point. Ajoutez une entrée explicite pour les routes comme
/utilisateurs/jean.dupont. https://next-intl.dev/docs/routing/middleware
Composants clients
NextIntlClientProvidersans propmessagesenvoie TOUS les messages au client. Passezmessages={pick(messages, 'Namespace')}oumessages={null}pour les limiter. https://next-intl.dev/docs/environments/server-client-components- Privilégiez la traduction dans un Server Component et passez les libellés comme props ou
childrenau Client Component. https://next-intl.dev/docs/environments/server-client-components onErroretgetMessageFallbackne peuvent pas être passés depuis un Server Component. Définissez-les dans votre propre fournisseur'use client'imbriqué dans le fournisseur serveur, qui conserve l'héritage de la locale et des messages, donc ne les passez pas manuellement. https://next-intl.dev/docs/usage/configuration
Messages
- Les clés et les espaces de noms ne peuvent pas contenir
., ce qui signifie imbrication. Utilisez uniquement du JSON imbriqué. https://next-intl.dev/docs/usage/translations - Les noms d'arguments ICU et les valeurs
selectacceptent les lettres, les chiffres et_, pas de tirets : mappezfr-FRversfr_FR.selectnécessite un casother. https://next-intl.dev/docs/usage/translations - Les balises auto-fermantes nécessitent une balise fermante dans les messages :
<br></br>. https://next-intl.dev/docs/usage/translations - Utilisez
getTranslations({locale, namespace})dans les Server Actions, les métadonnées et les Route Handlers, où la locale peut ne pas être déduite. https://next-intl.dev/docs/environments/actions-metadata-route-handlers
Tests
- Vitest avec
createNavigation:server.deps.inline: ['next-intl']. Jest :transformIgnorePatterns: ['node_modules/(?!next-intl)/']. next-intl est uniquement ESM. https://next-intl.dev/docs/environments/testing
Anciens motifs
| Ancien | Actuel |
|---|---|
src/middleware.ts | src/proxy.ts sur Next.js 16, même code createMiddleware |
setRequestLocale(locale) en haut de chaque layout et page | next/root-params dans i18n/request.ts, le rendu statique fonctionne sans |
getRequestConfig(async ({requestLocale}) => ...) | getRequestConfig(async ({locale}) => ...) avec un fallback rootParams.locale() |
Clés de message plates "HomePage.title" | Objets imbriqués {"HomePage": {"title": ...}} |
t.raw HTML dans dangerouslySetInnerHTML | t.rich (React) ou t.markup (chaînes), t.raw seulement pour ignorer l'analyse, assaini |
Détails : references/routing.md et references/messages.md.
Fichiers de référence
| Fichier | Lire pour |
|---|---|
| references/setup.md | Plugin, configuration de requête, valeurs par défaut du fournisseur, locale sans routage, stockage des messages, Pages Router |
| references/routing.md | defineRouting, segment [locale], proxy.ts, matcher, next/root-params, rendu statique, localePrefix, domaines, cookie, liens alternatifs, chemins localisés, export statique, dépannage |
| references/navigation.md | createNavigation, Link, useRouter, usePathname, redirect, getPathname, sélecteur de locale, href typé |
| references/messages.md | useTranslations, espaces de noms, pluriels et sélecteurs ICU, texte enrichi, t.markup, t.raw, t.has, tableaux, messages manquants, onError, fuseau horaire, now |
| references/formatting.md | useFormatter : dates, temps relatif, plages, nombres, listes, noms d'affichage, squelettes ICU, formats globaux |
| references/server-and-client.md | Composants serveur vs client, sélection des messages, métadonnées, Server Actions, Zod, Route Handlers, plan du site, images OG, fichiers 404 et d'erreur |
| references/extraction.md | Expérimental useExtracted et getExtracted, options experimental du plugin, fichiers PO, précompilation, codecs personnalisés, monorepos |
| references/typescript-and-tooling.md | Augmentation AppConfig, arguments typés, tests avec Jest et Vitest, Storybook, noyau use-intl, prérequis runtime, linting, gestion des traductions, conventions d'agent |
Pages explorées : SOURCES.md.