next-intl nextjs 16: cache de composants via root-params
Maîtrisez l'intégration de next-intl avec nextjs 16 grâce à next/root-params pour activer en toute sécurité le cache de composants sans prop-drilling de la locale.

De nombreuses équipes d’ingénierie ont du mal à équilibrer l’efficacité du rendu serveur avec une internationalisation robuste. Lorsqu’ils migrent vers des versions modernes de Next.js, les développeurs découvrent souvent que la résolution de locale liée à la requête peut entrer en conflit avec le rendu statique et les scopes de Server Components mis en cache.
Ce guide explique comment configurer next-intl avec Next.js 16 Cache Components en utilisant next/root-params, afin que les Server Components imbriqués puissent résoudre la locale active sans la transmettre à travers chaque layout, page et composant.
next/root-params: Les versions récentes de Next.js exposent les segments de route racine comme[locale]sous forme de fonctions getter async telles quelocale(), afin que les Server Components puissent lire la locale active sans prop-drilling.cacheComponents: Active Next.js Cache Components et la directive Reactuse cache.proxy.ts: Dans Next.js 16,middleware.tsest déprécié et renommé enproxy.ts.
À savoir également :
requestLocale: Dans next-intl v4,getRequestConfigreçoitrequestLocale, qui doit être awaited, et la configuration retournée doit inclurelocale.- Pas de prop-drilling : Les Server Components imbriqués peuvent résoudre directement la locale au lieu de la recevoir depuis les layouts parents.
- Limites actuelles :
next/root-paramsest destiné aux Server Components. Les Client Components ne peuvent pas l’importer ni l’appeler directement ; passez la locale en prop, ou utilisez les API de routing côté client si nécessaire.
Qu’est-ce que le caching next-intl dans Next.js 16 ?
Dans cette configuration, le caching next-intl signifie utiliser des Server Components localisés avec la directive React use cache, tout en résolvant la locale active via next/root-params au lieu des headers de requête.
Traditionnellement, les bibliothèques d’internationalisation s’appuyaient souvent sur la requête entrante pour déterminer la langue active. Elles pouvaient lire le header Accept-Language, les cookies ou d’autres données de requête, puis transmettre la locale dans l’application.
Cela fonctionne pour le rendu dynamique, mais devient problématique lorsque vous voulez mettre en cache ou prérendre certaines parties de l’UI. Les scopes de Server Components mis en cache doivent éviter les API non mises en cache liées à la requête, comme headers() et cookies().
Next.js Cache Components rend cette frontière plus explicite. Si un composant est mis en cache, il doit dépendre d’entrées sûres pour le cache. Pour les routes localisées, le segment d’URL lui-même est une meilleure clé de cache que les headers de requête.
Le problème : caching et résolution de locale
Avant next/root-params, les développeurs utilisant next-intl avec le rendu statique s’appuyaient souvent sur setRequestLocale(locale) pour rendre la locale disponible sans forcer le rendu dynamique.
Cette approche fonctionne, mais elle ajoute du boilerplate. La fonction doit être appelée dans chaque layout et page qui doit être rendu statiquement, car Next.js peut rendre les layouts et les pages indépendamment.
next/root-params fournit une approche plus propre. Il permet aux Server Components de lire directement les params de route racine comme [locale], sans transmettre la locale via des props.
next/root-params expose des getters async générés pour les params racine, comme locale() ou lang().
| Approche d’architecture | Résolution de locale | Compatible avec use cache ? |
Boilerplate |
|---|---|---|---|
| Rendu lié à la requête | headers() / cookies() |
Peu adapté à l’intérieur des scopes mis en cache | Faible |
| Forçage statique | setRequestLocale(locale) |
Oui | Élevé |
| Pattern root params | next/root-params |
Oui, pour les Server Components | Faible |
Versions et limites actuelles
Utilisez ce pattern uniquement lorsque vos versions installées prennent en charge les API ci-dessous :
- Next.js 16 avec
cacheComponents - Une version de Next.js qui inclut
next/root-params - Une version récente de next-intl v4
- React 19
next/root-params est passé par des étapes expérimentales et documentées pendant la série de releases Next.js 16. Vérifiez que votre version installée de Next.js expose next/root-params avant de remplacer setRequestLocale() en production.
next/root-params est le successeur de l’ancienne API unstable_rootParams. Il permet de générer des fonctions getter async à partir de params de route racine comme locale() ou lang().
Limites actuelles :
- Les Client Components ne peuvent pas importer ni appeler directement
next/root-params. - Les Server Actions ne sont pas prises en charge.
- Les Route Handlers ne sont pas pris en charge.
next/root-paramsest destiné aux Server Components.- Si vous avez besoin de la locale dans un Client Component, passez-la depuis un Server Component ou lisez les params de route avec des API de routing côté client comme
useParams. - Testez toujours vos versions exactes de Next.js et next-intl avant d’expédier ce pattern en production.
Activer Cache Components et root params
Activez Cache Components et root params dans next.config.ts.
// next.config.ts
import createNextIntlPlugin from 'next-intl/plugin';
import type { NextConfig } from 'next';
const withNextIntl = createNextIntlPlugin();
const nextConfig: NextConfig = {
cacheComponents: true,
experimental: {
rootParams: true,
},
};
export default withNextIntl(nextConfig);
cacheComponents est une option de premier niveau. Dans Next.js 16, elle contrôle le modèle de programmation Cache Components et unifie les anciennes configurations ppr, useCache et dynamicIO.
rootParams peut être activé explicitement sous experimental, tandis que cacheComponents active le modèle de caching qui rend ce pattern utile.
Structure d’application requise
Pour que next/root-params expose [locale], le segment de locale doit faire partie de l’arbre du root layout. Cela signifie que votre root layout doit se trouver dans app/[locale]/layout.tsx.
Structure recommandée :
src/
├── i18n/
│ ├── routing.ts
│ └── request.ts
├── proxy.ts
└── app/
└── [locale]/
├── layout.tsx
└── page.tsx
Pour ce pattern, évitez de placer un root app/layout.tsx au-dessus de [locale], car [locale] doit faire partie de l’arbre du root layout pour être exposé via next/root-params.
Les paramètres de route plus profonds dans l’arbre restent accessibles via la prop params. Par exemple, dans app/[locale]/blog/[slug]/page.tsx, locale peut être un root param, tandis que slug reste un paramètre de route classique.
Configurer proxy.ts
Dans Next.js 16, middleware.ts est déprécié et renommé en proxy.ts. La fonction exportée doit être nommée proxy, ou vous pouvez utiliser la forme d’export par défaut prise en charge.
// src/proxy.ts
import createMiddleware from 'next-intl/middleware';
import { routing } from './i18n/routing';
export const proxy = createMiddleware(routing);
export const config = {
matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)',
};
Le matcher exclut les chemins internes courants, les routes API, les chemins internes Vercel et les fichiers avec extensions comme favicon.ico.
Mise en garde sur le runtime
proxy.ts utilise le runtime Node.js. L’option de configuration runtime n’est pas disponible dans les fichiers Proxy.
Si vous avez spécifiquement besoin du comportement Edge runtime, middleware.ts fonctionne encore dans Next.js 16, mais il est déprécié. Il devrait être supprimé dans une version future.
Configurer la request config next-intl
Dans next-intl v4, getRequestConfig reçoit requestLocale lorsque vous utilisez le routing basé sur la locale. Vous devez l’await et retourner la locale finale.
Vous pouvez aussi vous rabattre sur next/root-params lorsque requestLocale n’est pas disponible dans les scopes de Server Components mis en cache.
// src/i18n/request.ts
import { locale as getRootLocale } from 'next/root-params';
import { hasLocale } from 'next-intl';
import { getRequestConfig } from 'next-intl/server';
import { notFound } from 'next/navigation';
import { routing } from './routing';
export default getRequestConfig(async ({ requestLocale }) => {
let locale = await requestLocale;
if (!locale) {
const paramValue = await getRootLocale();
if (hasLocale(routing.locales, paramValue)) {
locale = paramValue;
} else {
notFound();
}
}
return {
locale,
messages: (await import(`../../messages/${locale}.json`)).default,
};
});
Cela supprime la nécessité d’appeler setRequestLocale(locale) dans chaque layout et page pour ce cas d’usage centré sur le caching.
En dehors de cette configuration, setRequestLocale() reste l’approche documentée de next-intl pour activer le rendu statique.
Simplifier le localized root layout
Votre localized root layout peut maintenant lire directement la locale active depuis next/root-params.
// src/app/[locale]/layout.tsx
import { locale as getRootLocale } from 'next/root-params';
import { hasLocale } from 'next-intl';
import { notFound } from 'next/navigation';
import type { ReactNode } from 'react';
import { routing } from '@/i18n/routing';
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}
type LocaleLayoutProps = {
children: ReactNode;
};
export default async function LocaleLayout({ children }: LocaleLayoutProps) {
const locale = await getRootLocale();
if (!hasLocale(routing.locales, locale)) {
notFound();
}
return (
<html lang={locale}>
<body>{children}</body>
</html>
);
}
generateStaticParams() reste important pour prérendre les routes localisées. Avec Cache Components activé, les paramètres racine ont besoin de valeurs statiques pour les shells prérendables.
Utiliser use cache avec des composants localisés
Une fois la locale disponible via next/root-params, les Server Components mis en cache peuvent l’utiliser comme partie de leur entrée sûre pour le cache.
// src/app/[locale]/pricing/PricingSection.tsx
import { locale as getRootLocale } from 'next/root-params';
import { getTranslations } from 'next-intl/server';
async function fetchPricingTiers(locale: string) {
return [
{ id: '1', title: locale === 'de' ? 'Basis' : 'Basic' },
{ id: '2', title: locale === 'de' ? 'Profi' : 'Pro' },
];
}
export default async function PricingSection() {
'use cache';
const locale = await getRootLocale();
const t = await getTranslations('PricingSection');
const tiers = await fetchPricingTiers(locale);
return (
<section className="rounded-xl border border-neutral-200 p-6">
<h2 className="text-xl font-bold">{t('heading')}</h2>
<ul className="mt-4 space-y-2">
{tiers.map((tier) => (
<li key={tier.id} className="text-neutral-600">
{tier.title}
</li>
))}
</ul>
</section>
);
}
Cela permet aux composants profondément imbriqués de récupérer des traductions et des données localisées sans recevoir locale comme prop depuis la page ou le layout.
Next.js peut suivre quels getters de paramètres racine une fonction mise en cache utilise. Cela signifie que la sortie mise en cache peut être séparée par le paramètre racine pertinent, comme locale, au lieu de dépendre des headers de requête.
Vérifier le build de production
Lancez un build de production :
npm run build
Les routes entièrement prérendables doivent apparaître comme statiques ou prérendues dans la sortie du build.
Si une route localisée devient dynamique, inspectez le chemin de rendu pour rechercher :
headers()cookies()- accès à des données non mises en cache
- API liées à la requête
generateStaticParams()manquant- logique de route qui empêche le prérendu
Les fonctions mises en cache ne peuvent pas accéder directement à cookies(), headers() ou searchParams ; lisez-les en dehors du scope mis en cache et transmettez-les.
Toutes les routes localisées n’ont pas besoin d’être statiques. L’objectif est de rendre les routes statiques et mises en cache possibles sans prop-drilling de la locale.
Pièges courants
1. Garder app/layout.tsx au-dessus de [locale]
Si [locale] ne fait pas partie de l’arbre du root layout, next/root-params ne peut pas l’exposer comme root param.
Déplacez le root layout vers :
app/[locale]/layout.tsx
2. Traiter searchParams comme une fonction
Dans les pages App Router modernes de Next.js, searchParams est une prop Promise. Await-la directement.
Correct :
const params = await searchParams;
Incorrect :
const params = await searchParams();
Pour les Client Components, utilisez la fonction React use() pour lire la Promise au lieu de rendre le composant async.
3. Utiliser les anciennes conventions middleware
middleware.ts fonctionne encore dans Next.js 16, mais il est déprécié.
Utilisez :
proxy.ts
Et exportez soit une fonction par défaut, soit une fonction nommée proxy :
export const proxy = createMiddleware(routing);
4. Utiliser des versions obsolètes de next-intl
Utilisez une version récente de next-intl v4. next-intl v3 ne fournit pas le même comportement de request config nécessaire pour ce pattern.
Avant de publier un pin de package exact, vérifiez la version actuelle du package avec votre package manager.
5. S’attendre à un support direct dans les Client Components, Server Actions ou Route Handlers
next/root-params est destiné aux Server Components. Les Client Components ne peuvent pas l’importer ni l’appeler directement, et il ne prend pas actuellement en charge les Server Actions ni les Route Handlers.
Si vous avez besoin de la locale dans un Client Component, passez-la depuis un Server Component ou utilisez des API de routing côté client comme useParams.
Si vous avez besoin de la locale dans une Server Action, passez-la explicitement comme argument depuis le composant qui appelle l’action.
FAQ
Comment utiliser use cache avec next-intl ?
Activez cacheComponents: true dans next.config.ts.
Si votre version de Next.js inclut next/root-params, activez également root params et configurez getRequestConfig pour résoudre la locale depuis requestLocale, avec next/root-params comme fallback lorsque nécessaire.
// next.config.ts
const nextConfig = {
cacheComponents: true,
experimental: {
rootParams: true,
},
};
Pourquoi la gestion de locale peut-elle casser le rendu statique ?
La gestion de locale peut casser le rendu statique lorsqu’elle dépend d’API liées à la requête comme headers() ou cookies(). Ces API rendent le rendu spécifique à la requête, ce qui entre en conflit avec le rendu statique et les scopes de Server Components mis en cache.
Qu’est-ce que next/root-params ?
next/root-params est une API serveur de Next.js qui expose les params de route racine sous forme de fonctions getter async.
Par exemple, si votre segment dynamique racine est [locale], vous pouvez utiliser :
import { locale } from 'next/root-params';
const value = await locale();
Si votre segment est [lang], le getter généré est lang().
Les noms de paramètres racine doivent être des identifiants de fonction JavaScript valides, donc évitez les noms comme [post-slug] pour les root params auxquels vous voulez accéder de cette manière.
Ai-je encore besoin de setRequestLocale ?
Pour ce pattern next/root-params et Cache Components, vous n’avez généralement pas besoin d’appeler setRequestLocale() dans chaque page et layout.
En dehors de cette configuration, ou sur les versions de Next.js où next/root-params n’est pas disponible, setRequestLocale() reste l’approche documentée de next-intl pour activer le rendu statique.
Puis-je utiliser next/root-params dans unstable_cache ?
Non. Utilisez plutôt la directive React use cache avec Cache Components.
next/root-params est conçu pour fonctionner avec use cache, où Next.js peut suivre les getters de paramètres racine utilisés par la fonction mise en cache.
Conclusion
Next.js 16 Cache Components rend les frontières de rendu plus explicites, et les apps internationalisées ont besoin d’une résolution de locale qui fonctionne à l’intérieur de ces frontières.
En combinant cacheComponents, next/root-params et la configuration de requête next-intl v4, vous pouvez supprimer le prop-drilling répétitif de locale, éviter la résolution de locale basée sur les headers de requête dans les Server Components mis en cache, et garder les routes localisées éligibles au prérendu.
Si vous construisez des dashboards SaaS multilingues, des panels d’administration ou des produits de templates, ce pattern vous donne une base plus propre pour des Server Components localisés dans Next.js 16.
Build faster with Aniq UI
Les templates Aniq UI vous donnent des fondations Next.js prêtes pour la production avec TypeScript, Tailwind CSS, des layouts App Router, Server Components, animations et patterns React modernes.
Si vous construisez un dashboard SaaS, une landing page ou un panel d’administration, partir d’un template soigné peut vous faire gagner du temps de configuration sur le routing, les layouts, les états d’UI et les patterns de rendu.
Références
- Docs Next.js Proxy
- Guide de migration Next.js 16
- Docs Next.js Cache Components
- Docs Next.js
use cache - Docs de convention de fichier Next.js
page.js - Docs Next.js
useParams - Docs de configuration du routing next-intl
- Docs de configuration de requête next-intl
- Discussion next-intl root params
- Docs Next.js
next/root-paramsdans le repo Vercel


