Skip to main content

Пълно ръководство за интернационализация на Next.js

Настройте next-intl с App Router, конфигурирайте маршрутизирането по локал и автоматизирайте преводите с ИИ.

1

Инсталирайте next-intl

next-intl е единен пакет, който управлява маршрутизирането по локал, зареждането на съобщения и hooks за превод в Next.js App Router.

Terminal
npm install next-intl
Защо next-intl вместо next-i18next? next-intl е създаден за App Router и сървърни компоненти. next-i18next е проектиран за Pages Router и предлага ограничена поддръжка за App Router.
2

Създайте конфигурацията на i18n за заявките

Създайте два файла: src/i18n/request.ts за зареждане на съобщения и src/i18n/routing.ts за дефиниране на локалите. Те определят как next-intl намира съобщенията и маршрутите.

src/i18n/routing.ts
// 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);
Turbopack (пакетиращият инструмент по подразбиране в Next.js 15) изисква experimental.turbo.resolveAlias във Вашия next.config.js. Без него ще получавате грешки "Couldn't find next-intl config file".
3

Конфигурирайте middleware

Добавете middleware.ts за откриване на локала, пренаписване на URL адреси и пренасочвания. middleware прихваща всяка заявка и гарантира прилагането на правилния локал.

middleware.ts
// 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|.*\\..*).*)'],
};
middleware.ts ЗАДЪЛЖИТЕЛНО трябва да бъде в основната директория на проекта, а не в src/. Това е най-честата грешка при конфигурирането на next-intl.
4

Настройте структурата на папката [locale]

Преместете маршрутите на приложението в app/[locale]/. Добавете generateStaticParams, за да генерирате страниците за всеки локал по време на компилацията. Така се създава URL структурата /en/about, /de/about и т.н.

app/[locale]/layout.tsx
// app/[locale]/layout.tsx
import { routing } from '@/i18n/routing';

export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }));
}
ЗАДЪЛЖИТЕЛНО трябва да извикате setRequestLocale(locale) във всеки page.tsx и layout.tsx, който използва преводи. Без това Next.js преминава към динамично визуализиране и производителността при компилиране се влошава значително.
5

Актуализирайте основното оформление

Заредете съобщенията с getMessages() и ги подайте към NextIntlClientProvider в основното оформление за локала. Задайте атрибута lang на html от параметъра за локал.

app/[locale]/layout.tsx
// 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>
  );
}
NextIntlClientProvider изисква изрично зададено свойство locale. Ако го пропуснете, възникват трудно откриваеми грешки в клиентските компоненти.
6

Използвайте преводите в компоненти

Сървърните компоненти използват getTranslations (async, await). Клиентските компоненти използват useTranslations (hook). Изберете според мястото на визуализиране на компонента — сървърните компоненти изцяло изключват преводите от JavaScript пакета.

app/[locale]/page.tsx
// 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')} />;
}
Предпочитайте сървърни компоненти за преведеното съдържание. Така низовете за превод остават извън клиентския JavaScript пакет и времето за зареждане намалява.
7

Добавете SEO: метаданни и hreflang

Използвайте generateMetadata, за да създавате заглавия и описания на страниците за всеки локал. Добавете alternates.languages за тагове hreflang, за да могат търсачките да откриват всички езикови версии на всяка страница.

app/[locale]/layout.tsx
// 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}`])
      ),
    },
  };
}
При компилации във Vercel може да се генерира localhost като каноничен URL адрес, ако metadataBase не е зададен. Винаги задавайте metadataBase в основното оформление към Вашия производствен домейн.
8

Обработвайте страниците за грешки и ненамерено съдържание

error.tsx и not-found.tsx изискват специална обработка, защото могат да се визуализират извън обичайното оформление за локала. Основният not-found.tsx изисква собствена конфигурация на i18n доставчик, за да показва локализирани съобщения за грешки.

app/[locale]/error.tsx
// 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>
  );
}
Next.js визуализира локализираната Ви страница 404 само когато notFound() е извикана изрично в кода. За неизвестни маршрути без съответстваща страница се показва стандартната страница 404 на Next.js, а не локализираната Ви версия.
9

Автоматизирайте преводите

След като завършите настройката на i18n, превеждайте файловете със съобщения чрез ИИ направо от Вашата IDE или използвайте i18n Agent CLI във Вашия CI/CD пайплайн за автоматизиран превод при всяко внедряване.

Terminal
# 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)
Използвайте next-intl-localechain за интелигентен резервен избор на локал — потребител с pt-BR ще вижда преводите за pt-PT, вместо съдържанието да преминава към английски, когато не е наличен бразилски португалски.

Автоматизирайте контрола на качеството на превода

Откривайте липсващи ключове и повредени заместители чрез i18n-validate, преди да достигнат до потребителите. Тествайте интерфейса си с фиктивни преводи чрез i18n-pseudo, преди да са готови истинските преводи.

Инструменти с отворен код за i18n в Next.js

Тези пакети с отворен код решават често срещани затруднения в процесите за интернационализация на Next.js.

next-intl-localechain

Стандартният next-intl преминава направо към Вашия локал по подразбиране, когато липсва превод. Потребител с бразилски португалски вижда английски вместо напълно подходящите преводи за pt-PT. next-intl-localechain добавя интелигентни резервни вериги — той рекурсивно обединява преводите от сродни локали, така че потребителите на регионални варианти винаги да виждат най-близкия наличен превод.

src/i18n/request.ts
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'
}));
Автоматично обединява рекурсивно преводите по веригите от локали
Вградени вериги за португалски, испански, френски, немски и други езици
Пропуска липсващите файлове със съобщения без грешки
Настройка с един ред — обвива съществуващия Ви getRequestConfig
Вижте в GitHub

@i18n-agent/cli

Инструмент за команден ред, с който превеждате файловете със съобщения на Next.js, без да напускате терминала. Превеждайте файлове директно, проверявайте състоянието на задачите и изтегляйте резултатите. Работи в CI/CD пайплайни с удостоверяване чрез API ключ за напълно автоматизирани процеси на локализация.

Terminal
# 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,es
Превеждайте JSON, YAML, PO и други i18n файлови формати от терминала
Готов за CI/CD — удостоверяване чрез променлива на средата за автоматизирани пайплайни
Следете състоянието на задачите, възобновявайте неуспешните задачи и изтегляйте резултатите
Машинночетим JSON изход за скриптове и автоматизация
Вижте в GitHub

Често срещани затруднения

"Unable to find next-intl locale"

Заявката не е съвпаднала с правилата на middleware. Проверете: намира ли се middleware.ts в основната директория на проекта? Изключва ли правилно шаблонът matcher статичните файлове? Включен ли е локалът в конфигурацията за маршрутизиране?

Неочаквано динамично визуализиране

setRequestLocale(locale) липсва от страница или оформление. Без нея next-intl използва заглавки/бисквитки, за да открие локала, което налага динамично визуализиране и възпрепятства статичното генериране.

Паралелните маршрути не работят с i18n

Паралелните маршрути (@modal) и прихващащите маршрути ((.)photo) имат известни несъвместимости с динамичния сегмент [locale]. Като временно решение за тези усъвършенствани модели на маршрутизиране използвайте маршрутизиране чрез middleware.

При смяна на езика текущият маршрут се губи

Когато сменяте локала, запазете текущия pathname чрез usePathname() и заменете само сегмента за локала. Внимавайте с параметрите на динамичните маршрути — те трябва да бъдат определени наново за новия локал.

Препоръчителна файлова структура

Project Structure
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

Изпробвайте i18n Agent сега

Пуснете тук Вашия файл за превод

JSON, YAML, PO, XML, CSV, Markdown, Properties

или натиснете, за да изберете файл

Целеви езици

Не се изисква регистрацияНезабавна оценка

Резервни езикови версии с next-intl-localechain

Когато липсва ключ за превод в регионална езикова версия като pt-BR, next-intl преминава директно към езиковата версия по подразбиране, вместо първо да провери родителската версия pt.

Terminal
npm install next-intl-localechain
Configuration
import { 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`),
});

Вижте нашето ръководство за резервни езикови версии за пълния списък с поддържани рамки и 75 вградени вериги. Learn more →

Често задавани въпроси