Skip to main content

Potpun vodič za Next.js internacionalizaciju

Postavite next-intl uz App Router, konfigurirajte usmjeravanje lokalnih postavki i automatizirajte prevođenje pomoću AI.

1

Instalirajte next-intl

next-intl je jedan paket koji obrađuje usmjeravanje lokala, učitavanje poruka i hook funkcije prijevoda za Next.js App Router.

Terminal
npm install next-intl
Zašto next-intl umjesto next-i18next? next-intl izrađen je za App Router i poslužiteljske komponente. next-i18next osmišljen je za Pages Router i ima ograničenu podršku za App Router.
2

Napravite i18n konfiguraciju zahtijeva

Izradite dvije datoteke: src/i18n/request.ts za učitavanje poruka i src/i18n/routing.ts za definicije lokalnih postavki. One određuju kako next-intl razrješava poruke i rute.

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 (zadani bundler u Next.js 15) zahtijeva experimental.turbo.resolveAlias u next.config.js. Bez toga dobivate grešku „Couldn't find next-intl config file".
3

Konfigurirajte middleware

Dodajte middleware.ts za otkrivanje lokala, prepisivanje URL adresa i preusmjeravanja. Middleware presreće svaki zahtjev i osigurava primjenu ispravnog lokala.

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 MORA se nalaziti u korijenskom direktoriju Vašeg projekta, a ne unutar src/. To je najčešća konfiguracijska pogreška pri upotrebi next-intl.
4

Postavite strukturu mape [locale]

Premjestite rute aplikacije u app/[locale]/. Dodajte generateStaticParams kako biste tijekom izgradnje generirali stranice za svaku lokalnu postavku. Time nastaje struktura URL-ova /en/about, /de/about itd.

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

export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }));
}
MORATE pozvati setRequestLocale(locale) u svakoj datoteci page.tsx i layout.tsx koja upotrebljava prijevode. Bez toga Next.js prelazi na dinamičko prikazivanje, a performanse izgradnje znatno se pogoršavaju.
5

Ažurirajte korijenski raspored

Učitajte poruke pomoću getMessages() i proslijedite ih komponenti NextIntlClientProvider u korijenskom rasporedu lokalne postavke. Postavite atribut lang elementa html iz parametra lokalne postavke.

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 zahtijeva izričit prop locale. Njegovo izostavljanje izaziva suptilne pogreške u klijentskim komponentama koje se teško otklanjaju.
6

Upotrebljavajte prijevode u komponentama

Poslužiteljske komponente upotrebljavaju getTranslations (async, await), a klijentske useTranslations (hook). Odaberite prema mjestu prikaza komponente — poslužiteljske komponente u potpunosti zadržavaju prijevode izvan JavaScript paketa.

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')} />;
}
Za prevedeni sadržaj prednost dajte poslužiteljskim komponentama. One zadržavaju nizove prijevoda izvan klijentskog JavaScript paketa i skraćuju vrijeme učitavanja za korisnike.
7

Dodajte SEO: metapodatke i hreflang

Upotrijebite generateMetadata za izradu naslova i opisa stranica prilagođenih svakoj lokalnoj postavci. Dodajte alternates.languages za oznake hreflang kako bi tražilice otkrile sve jezične inačice svake stranice.

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}`])
      ),
    },
  };
}
Izgradnja na Vercelu može generirati localhost kao kanonski URL ako metadataBase nije postavljen. Uvijek postavite metadataBase u korijenskom rasporedu na svoju produkcijsku domenu.
8

Obradite stranice pogreške i nepostojeće stranice

error.tsx i not-found.tsx zahtijevaju posebnu obradu jer se mogu prikazati izvan uobičajenog rasporeda lokalne postavke. Korijenski not-found.tsx zahtijeva vlastito postavljanje pružatelja i18n za prikaz lokaliziranih poruka o pogreškama.

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 prikazuje lokaliziranu 404 stranicu samo kada u kodu izričito pozovete notFound(). Nepoznate rute bez odgovarajuće stranice prikazuju zadani Next.js 404, a ne lokaliziranu verziju.
9

Automatizirajte prevođenje

Nakon dovršetka postavljanja i18n prevedite datoteke poruka pomoću AI izravno iz IDE-a ili upotrijebite i18n Agent CLI u CI/CD pipelineu za automatizirano prevođenje pri svakoj implementaciji.

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)
Upotrijebite next-intl-localechain za pametni pričuvni odabir lokalnih postavki — korisnik postavke pt-BR vidi prijevode za pt-PT umjesto engleskog kada brazilski portugalski nije dostupan.

Automatizirajte kvalitetu prijevoda

Otkrijte nedostajuće ključeve i neispravna mjesta za varijable pomoću i18n-validate prije objavljivanja. Testirajte UI lažnim prijevodima pomoću i18n-pseudo prije nego što stignu pravi prijevodi.

Alati otvorenog izvornog koda za Next.js i18n

Ovi paketi otvorenog izvornog koda rješavaju uobičajene probleme u tokovima Next.js internacionalizacije.

next-intl-localechain

Standardni next-intl izravno prelazi na zadanu lokalnu postavku kada prijevod nedostaje. Korisnik brazilskog portugalskog vidi engleski umjesto potpuno valjanih prijevoda za pt-PT. next-intl-localechain dodaje pametne pričuvne lance — dubinski spaja prijevode iz povezanih lokalnih postavki kako bi regionalni korisnici uvijek vidjeli najbliži dostupan prijevod.

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'
}));
Automatski dubinski spaja prijevode duž lanaca lokalnih postavki
Ugrađeni lanci za portugalski, španjolski, francuski, njemački i druge jezike
Neprimjetno preskače nedostajuće datoteke poruka bez pogrešaka
Postavljanje u jednom redu — obavija postojeći getRequestConfig
Pogledajte na GitHub platformi

@i18n-agent/cli

Alat naredbenog retka za prevođenje Next.js datoteka poruka bez napuštanja terminala. Izravno prevodite datoteke, provjeravajte stanje zadatka i preuzimajte rezultate. Radi u CI/CD pipelineima uz autentikaciju API ključem za potpuno automatizirane lokalizacijske tijekove rada.

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
Prevodite JSON, YAML, PO i druge i18n formate iz terminala
Spremno za CI/CD — potvrda identiteta varijablom okruženja za automatizirane pipeline procese
Pratite stanje zadatka, nastavite neuspjele zadatke i preuzmite rezultate
Strojni čitljiv JSON izlaz za skripte i automatizaciju
Pogledajte na GitHub platformi

Uobičajene zamke

„Unable to find next-intl locale"

Middleware nije obuhvatio zahtjev. Provjerite: nalazi li se middleware.ts u korijenu projekta, isključuje li matcher pravilno statičke datoteke i je li lokalna postavka uključena u konfiguraciju usmjeravanja.

Neočekivano dinamičko prikazivanje

setRequestLocale(locale) nedostaje na stranici ili u rasporedu. Bez njega next-intl koristi zaglavlja i kolačiće za otkrivanje lokala, što nameće dinamičko prikazivanje i sprječava statičko generiranje.

Paralelne rute ne rade s i18n

Paralelne rute (@modal) i rute presretanja ((.)photo) imaju poznate nekompatibilnosti s dinamičkim segmentom [locale]. Za te napredne obrasce kao zaobilazno rješenje upotrebljavajte usmjeravanje putem sloja middleware.

Promjena jezika gubi trenutnu rutu

Pri promjeni lokalne postavke sačuvajte trenutačnu putanju pomoću usePathname() i zamijenite samo segment lokalne postavke. Budite oprezni s parametrima dinamičke rute — moraju se ponovno razriješiti za novu lokalnu postavku.

Preporučena struktura datoteka

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

Isprobajte i18n Agent odmah

Povucite datoteku za prijevod ovdje

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

ili kliknite za odabir

Ciljni jezici

Registracija nije potrebnaProcjena odmah

Pričuvni odabir lokalne postavke uz next-intl-localechain

Kada u regionalnoj lokalnoj postavci poput pt-BR nedostaje ključ prijevoda, next-intl izravno prelazi na zadanu lokalnu postavku umjesto da najprije provjeri nadređenu lokalnu postavku 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`),
});

Pogledajte naš vodič za rezervne lokale za cijelu listu podržanih sustava i 75 ugrađenih lanaca. Learn more →

Česta pitanja