Il existe deux façons de traduire un site Web Next.js. Le itinéraire du code: placez chaque itinéraire sous un app/[lang] segment, détecter la langue du visiteur dans proxy.js, chargez un dictionnaire de traduction par locale et affichez les balises hreflang avec le alternates champ de métadonnées. Le itinéraire sans code: ajoutez le script d'un service de traduction à votre mise en page racine et laissez-le traduire les pages rendues, avec des URL traduites servies à partir d'un sous-répertoire ou d'un sous-domaine pour le référencement.
La route de code vous donne un contrôle total et fonctionne mieux lorsque le texte réside dans votre base de code et qu'un développeur le maintient. La voie sans code est plus rapide lorsque le texte provient d'un CMS, lorsque des non-développeurs doivent modifier des traductions ou lorsque vous avez besoin de plusieurs langues à la fois. Ce guide présente les deux, basé sur la documentation Next.js 16, et se termine par une liste de contrôle pour le référencement multilingue dans tous les cas.
Principaux points à retenir
- Routeur d'applications : pages de nid sous
app/[lang], rediriger versproxy.js(appelémiddleware.jsavant Next.js 16), chargez les dictionnaires JSON dans les composants du serveur et pré-rendez les paramètres régionaux avecgenerateStaticParams. - Routeur de pages : utiliser le intégré
i18nconfigurer dansnext.config.js. Ça ne marche pas avecoutput: 'export'. - Next.js n'ajoute pas de hreflang pour vous. Dans le routeur d'applications, utilisez
alternates.languagesdansgenerateMetadata. - L'option sans code en est une
<Script>entrer dansapp/layout.tsx. Pour les pages traduites indexables, utilisez une configuration de sous-répertoire ou de sous-domaine plutôt qu'une traduction dans le navigateur uniquement. - Quel que soit l'itinéraire que vous choisissez, définissez
<html lang>, traduisez les titres et les descriptions et liez chaque version linguistique avec hreflang.
Option 1 : Internationaliser Next.js avec le routeur d'applications
Ceci suit le guide officiel d'internationalisation de Next.js (version 16.3 au moment de la rédaction).
Étape 1 : Placez vos itinéraires sous un segment linguistique
Déplacez vos pages et mises en page dans app/[lang]/. Chaque page reçoit ensuite les paramètres régionaux comme paramètre d'itinéraire :
// app/[lang]/page.tsx
export default async function Page({ params }: PageProps<'/[lang]'>) {
const { lang } = await params;
return <h1>{lang}</h1>;
}Le routage peut utiliser un sous-chemin (/fr/products) ou un domaine (my-site.fr/products). Le sous-chemin est plus simple à héberger et conserve toutes les langues sur un seul domaine.
Étape 2 : Détecter la langue et rediriger dans proxy.js
Dans Next.js 16, le middleware la convention de fichier a été renommée en proxy (il existe un codemod : npx @next/codemod@canary middleware-to-proxy .). Le proxy vérifie si l'URL possède déjà une locale et, dans le cas contraire, redirige :
// proxy.js
import { NextResponse } from 'next/server';
const locales = ['en', 'fr', 'de'];
function getLocale(request) {
// Read Accept-Language, e.g. with @formatjs/intl-localematcher and negotiator
return 'en';
}
export function proxy(request) {
const { pathname } = request.nextUrl;
const hasLocale = locales.some((l) => pathname.startsWith(`/${l}/`) || pathname === `/${l}`);
if (hasLocale) return;
request.nextUrl.pathname = `/${getLocale(request)}${pathname}`;
return NextResponse.redirect(request.nextUrl);
}
export const config = {
matcher: ['/((?!_next).*)'],
};Soyez prudent avec les redirections automatiques. Les conseils de Google pour sites multilingues recommande de laisser les utilisateurs choisir : “Envisagez d'ajouter des hyperliens vers d'autres versions linguistiques d'une page.” Rediriger uniquement lorsque l'URL n'a pas de paramètres régionaux, jamais loin d'un paramètre régional demandé par le visiteur (ou Googlebot) et toujours afficher un sélecteur de langue.
Étape 3 : Charger un dictionnaire par langue
Conservez un fichier JSON par langue et chargez-le sur le serveur :
// app/[lang]/dictionaries.ts
import 'server-only';
const dictionaries = {
en: () => import('./dictionaries/en.json').then((m) => m.default),
fr: () => import('./dictionaries/fr.json').then((m) => m.default),
};
export type Locale = keyof typeof dictionaries;
export const hasLocale = (l: string): l is Locale => l in dictionaries;
export const getDictionary = async (l: Locale) => dictionaries[l]();// app/[lang]/page.tsx
import { notFound } from 'next/navigation';
import { getDictionary, hasLocale } from './dictionaries';
export default async function Page({ params }: PageProps<'/[lang]'>) {
const { lang } = await params;
if (!hasLocale(lang)) notFound();
const dict = await getDictionary(lang);
return <button>{dict.products.cart}</button>;
}Étant donné que les pages App Router sont des composants serveur par défaut, les dictionnaires ne sont pas expédiés au navigateur. Les documents décrivent également next/root-params, qui permet à n'importe quel composant serveur de lire lang sans le faire passer à travers des accessoires.
Étape 4 : pré-rendre chaque langue et définir l'attribut de langue HTML
// app/[lang]/layout.tsx
export async function generateStaticParams() {
return [{ lang: 'en' }, { lang: 'fr' }, { lang: 'de' }];
}
export default async function RootLayout({ children, params }: LayoutProps<'/[lang]'>) {
return (
<html lang={(await params).lang}>
<body>{children}</body>
</html>
);
}Étape 5 : Ajouter hreflang et les balises canoniques
Next.js ne sait pas quelles pages sont des traductions les unes des autres, vous le déclarez donc. Avec le API de métadonnées, alternates génère à la fois les liens canoniques et hreflang :
// app/[lang]/pricing/page.tsx
export async function generateMetadata({ params }) {
const { lang } = await params;
return {
alternates: {
canonical: `https://example.com/${lang}/pricing`,
languages: {
en: 'https://example.com/en/pricing',
fr: 'https://example.com/fr/pricing',
de: 'https://example.com/de/pricing',
'x-default': 'https://example.com/en/pricing',
},
},
};
}Chaque version linguistique doit répertorier toutes les versions, y compris elle-même. Notre article sur balises hreflang auto-référencées explique pourquoi cela est important.
Des bibliothèques qui font le gros du travail
La documentation Next.js répertorie plusieurs bibliothèques pour le routage et la traduction, notamment next-intl, next-international, next-i18n-router, paraglide-next, lingui et tolgee. Ils ajoutent la pluralisation, le formatage des nombres et des dates et des clés de message de type sécurisé. Pour tout ce qui va au-delà d’un petit site, choisissez-en un plutôt que d’écrire le vôtre.
Option 1b : Le routeur de pages
Si votre projet utilise toujours le pages/ répertoire, Next.js dispose d'un routage i18n intégré depuis la version 10. Ajoutez les lieux à next.config.js:
module.exports = {
i18n: {
locales: ['en-US', 'fr', 'de'],
defaultLocale: 'en-US',
},
};Cela vous donne /fr/blog et /de/blog automatiquement et définit <html lang>. Selon le Pages Guide du routeur, deux limites comptent : vous ajoutez toujours hreflang vous-même (avec next/head), et “Le routage internationalisé ne s'intègre pas à output: 'export'”. Les exportations statiques nécessitent l’approche App Router ou une configuration différente.
Combien vous coûte l'itinéraire du code
La route de code est le bon choix pour une interface utilisateur de produit dont les chaînes vivent dans des composants. Cela devient cher pour tout le reste :
- Contenu en dehors de votre code (un CMS sans tête, des flux de produits, du contenu généré par les utilisateurs) a besoin de son propre pipeline de traduction.
- Chaque nouvelle chaîne a besoin d'une clé et d'une traduction dans chaque langue avant la sortie.
- Les non-développeurs ne peuvent pas corriger une traduction sans pull request, sauf si vous ajoutez un outil de gestion de traduction.
- Plus de langues signifie plus de fichiers pour rester synchronisé.
Option 2 : Traduisez un site Next.js sans modifier votre code
Un service de traduction de sites Web comme ConveyThis traduit le code HTML rendu par votre application Next.js, vous ne créez donc pas de dictionnaires ni ne modifiez d'itinéraires.
Étape 1 : Créez un compte et ajoutez votre domaine
Créer un compte ConveyThis, ajoutez votre domaine et choisissez vos langues source et cible.
Étape 2 : Ajoutez le script à votre mise en page racine
ConveyThis vous donne une URL de script avec votre clé API. Dans le routeur d'applications, ajoutez-le une fois app/layout.tsx avec next/script:
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://cdn.conveythis.com/javascript/conveythis.js?api_key=YOUR_API_KEY"
strategy="afterInteractive"
/>
</body>
</html>
);
}Le widget surveille les changements de page et la navigation côté client, de sorte que le contenu rendu par React après le premier chargement et les itinéraires qui changent sans rechargement complet sont également traduits. Il définit également les pages lang attribuer à la langue affichée. Les étapes générales sont les mêmes que dans notre Article d'aide à la traduction React et le JavaScript guide d'intégration.
Étape 3 : Choisissez une structure d’URL optimisée pour le référencement
Un script qui échange du texte dans le navigateur suffit aux visiteurs, mais les moteurs de recherche ont besoin d'une URL distincte pour chaque langue afin de l'indexer. Dans le tableau de bord ConveyThis, choisissez Sous-domaine (fr.example.com) ou Sous-répertoire (example.com/fr/) sous structure d'URL. Les pages traduites sont ensuite diffusées sur leurs propres URL avec des balises hreflang ajoutées. Pour un site personnalisé, le sous-domaine est généralement le choix le plus simple : votre hôte Next.js continue de servir le domaine principal et vous ajoutez un enregistrement CNAME par langue, tandis que le sous-répertoire signifie acheminer l'ensemble du domaine via ConveyThis. Les deux options figurent sur le plan d'affaires et au-dessus ; le article d'aide sur les sous-domaines et les sous-répertoires explique les enregistrements DNS dont chacun a besoin. Si votre domaine est déjà sur Cloudflare, le Configuration de Cloudflare Workers (O2O) maintient votre zone en place.
Étape 4 : Réviser et affiner les traductions
La traduction automatique vous permet d'obtenir une première version complète en quelques minutes. Utilisez ensuite l’éditeur visuel pour ajuster la formulation dans le contexte, ajouter des termes de marque au glossaire et inviter un traducteur ou un collègue ayant des rôles d’équipe. Voir la liste complète sur le page des fonctionnalités.
Itinéraire avec code ou itinéraire sans code ?
| Routeur d'applications i18n (code) | ConveyThis (pas de code) | |
|---|---|---|
| Configuration | Restructurer les itinéraires, ajouter un proxy, des dictionnaires, des métadonnées | Une balise de script plus DNS pour les URL SEO |
| D'où vient le texte | Vos dictionnaires | Quel que soit le rendu de la page, y compris le contenu du CMS |
| Qui édite les traductions | Développeurs (ou un TMS) | Toute personne disposant d'un accès au tableau de bord |
| hreflang | Vous l'ajoutez avec alternates | Ajouté avec des URL de sous-répertoire ou de sous-domaine |
| Idéal pour | Chaînes d'interface utilisateur de l'application, contrôle total | Sites marketing, contenu CMS, plusieurs langues |
| Coût | Temps développeur | Plan basé sur les mots et les langues (prix) |
De nombreuses équipes les combinent : i18n basé sur le code pour l'application connectée, un service de traduction pour le site marketing et un centre d'aide.
Liste de contrôle SEO multilingue pour Next.js
- Une URL par langue (
/fr/…oufr.example.com), jamais la même URL pour chaque langue. <html lang>correspond à la langue de la page.- Titre et méta description traduits pour chaque langue.
- Le canonique sur chaque page traduite pointe vers lui-même, et non vers la page anglaise.
- Hreflang répertorie toutes les versions linguistiques, y compris la page elle-même, ainsi que
x-default. - Le plan du site inclut toutes les URL de langue.
- Un commutateur de langue visible avec de vrais liens, pas seulement une liste déroulante qui change d'état.
- Aucune redirection forcée loin de la langue demandée par un visiteur.
Pour une vue d'ensemble, lisez notre aperçu du référencement multilingue.
FAQ
Next.js dispose-t-il d'une traduction intégrée ? Il a intégré l'internationalisation routage dans le routeur de pages et les modèles i18n documentés pour le routeur d'applications. Le texte traduit lui-même provient de vos dictionnaires, d’une bibliothèque ou d’un service de traduction.
Qu'est-il arrivé à middleware.js ? Dans Next.js 16, le middleware la convention de fichier était obsolète et renommée en proxy. La logique de détection des paramètres régionaux est la même.
Next.js ajoute-t-il automatiquement des balises hreflang ? Non. Utiliser alternates.languages dans les métadonnées du routeur d'applications, ou next/head dans le routeur de pages.
Puis-je traduire un site Next.js exporté statiquement ? Le routage i18n du routeur de pages ne fonctionne pas avec output: 'export', et le proxy n'est pas pris en charge pour les exportations statiques. Utiliser pré-généré [lang] itinéraires, ou un service de traduction qui dessert les pages traduites à partir de son propre sous-répertoire ou sous-domaine.
Vous souhaitez que votre site Next.js soit en plusieurs langues cette semaine au lieu du trimestre prochain ? Créer un compte ConveyThis, ajoutez le script à votre mise en page racine et choisissez la structure d'URL qui correspond à votre plan SEO.