
Ghidul complet pentru internaționalizarea Next.js
Configurați next-intl cu App Router, configurați rutarea după limbă și automatizați traducerile cu IA.
Instalați next-intl
next-intl este un singur pachet care gestionează rutarea după limbă, încărcarea mesajelor și hook-urile de traducere pentru Next.js App Router.
npm install next-intlCreați configurația solicitărilor i18n
Creați două fișiere: src/i18n/request.ts pentru încărcarea mesajelor și src/i18n/routing.ts pentru definirea limbilor și regiunilor. Acestea configurează modul în care next-intl identifică mesajele și rutele.
// src/i18n/routing.ts
import { defineRouting } from 'next-intl/routing';
import { createNavigation } from 'next-intl/navigation';
export const routing = defineRouting({
locales: ['en', 'de', 'ja', 'es'],
defaultLocale: 'en',
localePrefix: 'as-needed', // /about for en, /de/about for de
});
export const { Link, redirect, usePathname, useRouter } =
createNavigation(routing);Configurați middleware-ul
Adăugați middleware.ts pentru a gestiona detectarea limbii și regiunii, rescrierea adreselor URL și redirecționările. Middleware-ul interceptează fiecare solicitare și asigură aplicarea limbii și regiunii corecte.
// middleware.ts <- Must be in project ROOT, not src/
import createMiddleware from 'next-intl/middleware';
import { routing } from './src/i18n/routing';
export default createMiddleware(routing);
export const config = {
matcher: ['/((?!api|_next|.*\\..*).*)'],
};Configurați structura dosarului [locale]
Mutați rutele aplicației în app/[locale]/. Adăugați generateStaticParams pentru a genera pagini pentru fiecare limbă și regiune în timpul compilării. Astfel se creează structura URL /en/about, /de/about etc.
// app/[locale]/layout.tsx
import { routing } from '@/i18n/routing';
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}Actualizați dispunerea-rădăcină
Încărcați mesajele cu getMessages() și transmiteți-le către NextIntlClientProvider în dispunerea-rădăcină pentru limbă și regiune. Setați atributul html lang din parametrul locale.
// app/[locale]/layout.tsx
import { NextIntlClientProvider } from 'next-intl';
import { getMessages, setRequestLocale } from 'next-intl/server';
import { routing } from '@/i18n/routing';
import { notFound } from 'next/navigation';
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode;
params: { locale: string };
}) {
const { locale } = await params;
if (!routing.locales.includes(locale as any)) notFound();
setRequestLocale(locale);
const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider locale={locale} messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}Utilizați traducerile în componente
Componentele de server utilizează getTranslations (async, await). Componentele client utilizează useTranslations (hook). Alegeți în funcție de locul în care este randată componenta: componentele de server păstrează traducerile complet în afara pachetului JavaScript.
// Server Component (default)
import { getTranslations, setRequestLocale } from 'next-intl/server';
export default async function AboutPage({
params,
}: { params: { locale: string } }) {
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations('AboutPage');
return <h1>{t('title')}</h1>;
}
// Client Component ('use client')
'use client';
import { useTranslations } from 'next-intl';
export default function SearchBar() {
const t = useTranslations('SearchBar');
return <input placeholder={t('placeholder')} />;
}Adăugați SEO: metadate și hreflang
Utilizați generateMetadata pentru a produce titluri și descrieri de pagină specifice fiecărei limbi și regiuni. Adăugați alternates.languages pentru etichetele hreflang, astfel încât motoarele de căutare să descopere toate versiunile lingvistice ale fiecărei pagini.
// app/[locale]/layout.tsx or any page.tsx
import { getTranslations } from 'next-intl/server';
import { routing } from '@/i18n/routing';
export async function generateMetadata({
params,
}: { params: { locale: string } }) {
const { locale } = await params;
const t = await getTranslations({ locale, namespace: 'Metadata' });
return {
title: t('title'),
description: t('description'),
alternates: {
languages: Object.fromEntries(
routing.locales.map((l) => [l, `/${l}`])
),
},
};
}Gestionați paginile de eroare și paginile 404
error.tsx și not-found.tsx necesită o gestionare specială, deoarece pot fi randate în afara dispunerii obișnuite pentru limbă și regiune. Fișierul not-found.tsx de la rădăcină necesită propria configurare a furnizorului i18n pentru afișarea mesajelor de eroare localizate.
// app/[locale]/error.tsx
'use client';
import { useTranslations } from 'next-intl';
export default function Error() {
const t = useTranslations('Error');
return (
<div>
<h1>{t('title')}</h1>
<p>{t('description')}</p>
</div>
);
}
// app/not-found.tsx (root level -- needs own provider)
import { routing } from '@/i18n/routing';
export default async function GlobalNotFound() {
return (
<html lang={routing.defaultLocale}>
<body>
<h1>404 - Page Not Found</h1>
</body>
</html>
);
}Automatizați traducerile
După finalizarea configurării i18n, traduceți fișierele de mesaje cu IA direct din IDE sau utilizați i18n Agent CLI în fluxul CI/CD pentru traducere automată la fiecare lansare.
# In your IDE, ask your AI assistant:
> Translate messages/en.json to German, Japanese, and Spanish
✓ messages/de.json created (1.1s)
✓ messages/ja.json created (1.4s)
✓ messages/es.json created (1.0s)Automatizați controlul calității traducerilor
Instrumente cu sursă deschisă pentru Next.js i18n
Aceste pachete cu sursă deschisă rezolvă probleme frecvente din fluxurile de internaționalizare Next.js.
next-intl-localechain
next-intl standard revine direct la limba implicită când lipsește o traducere. Un utilizator de portugheză braziliană vede textul în engleză în locul traducerilor pt-PT disponibile și adecvate. next-intl-localechain adaugă lanțuri inteligente de variante de rezervă: combină recursiv traducerile din limbi și regiuni înrudite, astfel încât utilizatorii regionali să vadă întotdeauna cea mai apropiată traducere disponibilă.
import { getRequestConfig } from 'next-intl/server';
import { withLocaleChain } from 'next-intl-localechain';
export default getRequestConfig(withLocaleChain({
loadMessages: (locale) =>
import(`../../messages/${locale}.json`).then(m => m.default),
defaultLocale: 'en'
}));@i18n-agent/cli
Un instrument în linie de comandă pentru traducerea fișierelor de mesaje Next.js fără a părăsi terminalul. Traduceți direct fișierele, verificați starea activităților și descărcați rezultatele. Funcționează în fluxuri CI/CD cu autentificare prin cheie API, pentru procese de localizare complet automatizate.
# Install the CLI
npm install -g @i18n-agent/cli
# Authenticate
i18nagent login
# Translate your message files
i18nagent translate ./messages/en.json --lang de,ja,es
# Or use in CI/CD with an API key
export I18N_AGENT_API_KEY=your-key-here
i18nagent translate ./messages/en.json --lang de,ja,esCapcane frecvente
„Unable to find next-intl locale”
Solicitarea nu a corespuns regulii middleware-ului. Verificați dacă middleware.ts se află în rădăcina proiectului, dacă modelul matcher exclude corect fișierele statice și dacă limba și regiunea sunt incluse în configurația de rutare.
Randare dinamică neașteptată
setRequestLocale(locale) lipsește dintr-o pagină sau dispunere. Fără acesta, next-intl utilizează anteturi/module cookie pentru a detecta limba și regiunea, ceea ce impune randarea dinamică și împiedică generarea statică.
Rutele paralele nu funcționează cu i18n
Rutele paralele (@modal) și rutele de interceptare ((.)photo) prezintă incompatibilități cunoscute cu segmentul dinamic [locale]. Utilizați rutarea bazată pe middleware ca soluție alternativă pentru aceste modele avansate de rutare.
Schimbarea limbii pierde ruta curentă
Când schimbați limba, păstrați calea curentă utilizând usePathname() și înlocuiți numai segmentul locale. Acordați atenție parametrilor rutelor dinamice: aceștia trebuie rezolvați din nou pentru noua limbă și regiune.
Structura de fișiere recomandată
my-nextjs-app/
├── middleware.ts # Locale routing (project root!)
├── next.config.mjs
├── messages/
│ ├── en.json # Source messages
│ ├── de.json
│ └── ja.json
├── src/
│ ├── i18n/
│ │ ├── request.ts # Message loading config
│ │ └── routing.ts # Locale definitions
│ └── app/
│ └── [locale]/
│ ├── layout.tsx # Root locale layout
│ ├── page.tsx # Home page
│ ├── error.tsx # Localized error page
│ ├── not-found.tsx # Localized 404
│ └── about/
│ └── page.tsx
└── package.jsonÎncercați acum i18n Agent
Plasați aici fișierul de traducere
JSON, YAML, PO, XML, CSV, Markdown, Properties
sau faceți clic pentru a-l selecta
Limbi țintă
Mecanism de rezervă pentru setările regionale cu next-intl-localechain
Când lipsește o cheie de traducere într-o variantă regională precum pt-BR, next-intl trece direct la limba implicită, fără să verifice mai întâi limba părinte pt.
npm install next-intl-localechainimport { withLocaleChain } from 'next-intl-localechain';
export default withLocaleChain({
fallbacks: {
'pt-BR': ['pt', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
},
defaultLocale: 'en',
loadMessages: (locale) => import(`./messages/${locale}.json`),
});Consultați Ghidul nostru privind mecanismele de rezervă pentru setările regionale, care conține lista completă a cadrelor acceptate și cele 75 de lanțuri incluse. Learn more →