Skip to main content

Потпун водич за Next.js интернационализацију

Подесите next-intl са App Router, конфигуришите усмеравање локала и аутоматизујте преводе помоћу AI.

1

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

next-intl је један пакет који обрађује усмеравање локала, учитавање порука и hook функције превода за 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 (подразумевани bundler у 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 у коренском распореду локала. Поставите html атрибут lang из параметра локала.

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 захтева изричит prop 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 build може да генерише 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(). Непознате руте без одговарајуће странице приказују подразумевани Next.js 404, а не локализовану верзију.
9

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

Када завршите i18n подешавање, преведите датотеке порука помоћу AI директно из IDE окружења или користите i18n Agent CLI у CI/CD pipeline процесу за аутоматски превод при сваком постављању.

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 пре објављивања. Тестирајте UI лажним преводима помоћу i18n-pseudo пре него што стигну прави преводи.

Алати отвореног кода за Next.js i18n

Ови пакети отвореног кода решавају уобичајене проблеме у токовима 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 pipeline процесима са потврдом идентитета 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 — потврда идентитета променљивом окружења за аутоматизоване pipeline процесе
Пратите стање задатка, наставите неуспеле задатке и преузмите резултате
Машински читљив JSON излаз за скрипте и аутоматизацију
Погледајте на GitHub платформи

Уобичајене замке

„Unable to find next-intl locale"

Middleware није обухватио захтев. Проверите: да ли је middleware.ts у корену пројекта, да ли matcher правилно искључује статичке датотеке и да ли је локал укључен у конфигурацију усмеравања.

Неочекивано динамичко приказивање

setRequestLocale(locale) недостаје на страници или у распореду. Без њега next-intl користи заглавља и колачиће за откривање локала, што намеће динамичко приказивање и спречава статичко генерисање.

Паралелне руте не раде са i18n

Паралелне руте (@modal) и руте пресретања ((.)photo) имају познате некомпатибилности са динамичким сегментом [locale]. За ове напредне обрасце користите усмеравање преко middleware слоја као заобилазно решење.

Промена језика губи тренутну руту

При промени локала сачувајте тренутну путању помоћу 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 →

Честа питања