Skip to main content

Täydellinen opas Next.js:n kansainvälistämiseen

Ota next-intl käyttöön App Routerissa, määritä kieliversioreititys ja automatisoi käännökset tekoälyllä.

1

Asenna next-intl

next-intl on yksi paketti, joka hoitaa Next.js App Routerin kieliversioreitityksen, sanomien lataamisen ja käännöskoukut.

Terminal
npm install next-intl
Miksi next-intl eikä next-i18next? next-intl on rakennettu App Routerille ja palvelinkomponenteille. next-i18next suunniteltiin Pages Routerille, ja sen App Router -tuki on rajallinen.
2

Luo i18n-pyyntömääritys

Luo kaksi tiedostoa: src/i18n/request.ts sanomien lataamista varten ja src/i18n/routing.ts kieliversioiden määrittelyä varten. Ne määrittävät, miten next-intl ratkaisee sanomat ja reitit.

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:n oletuspaketoija) vaatii next.config.js-tiedostossa experimental.turbo.resolveAlias-asetuksen. Ilman sitä saat "Couldn't find next-intl config file" -virheitä.
3

Määritä middleware

Lisää middleware.ts käsittelemään kieliversion tunnistus, URL-osoitteiden uudelleenkirjoitus ja uudelleenohjaukset. Middleware sieppaa jokaisen pyynnön ja varmistaa, että oikeaa kieliversiota käytetään.

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 TÄYTYY sijoittaa projektisi juurihakemistoon, ei src/-hakemistoon. Tämä on next-intl:in yleisin yksittäinen määritysvirhe.
4

Määritä [locale]-kansiorakenne

Siirrä sovelluksesi reitit app/[locale]/-hakemiston sisään. Lisää generateStaticParams luomaan sivut jokaiselle kieliversiolle koontiaikana. Näin syntyy URL-rakenne /en/about, /de/about ja niin edelleen.

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

export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }));
}
Sinun TÄYTYY kutsua setRequestLocale(locale)-funktiota jokaisessa käännöksiä käyttävässä page.tsx- ja layout.tsx-tiedostossa. Ilman sitä Next.js siirtyy dynaamiseen hahmontamiseen ja koonnin suorituskyky heikkenee merkittävästi.
5

Päivitä juuriasettelu

Lataa sanomat getMessages()-funktiolla ja välitä ne juuren kieliversioasettelun NextIntlClientProviderille. Aseta html-elementin lang-määrite kieliversioparametrista.

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 tarvitsee eksplisiittisen locale-ominaisuuden. Sen puuttuminen aiheuttaa asiakaskomponenteissa vaikeasti jäljitettäviä hienovaraisia virheitä.
6

Käytä käännöksiä komponenteissa

Palvelinkomponentit käyttävät getTranslations-funktiota (asynkroninen, await). Asiakaskomponentit käyttävät useTranslations-koukkua. Valitse komponentin hahmonnuspaikan mukaan — palvelinkomponentit pitävät käännökset kokonaan JavaScript-paketin ulkopuolella.

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')} />;
}
Suosi käännetyssä sisällössä palvelinkomponentteja. Ne pitävät käännösmerkkijonot poissa asiakasohjelman JavaScript-paketista ja lyhentävät käyttäjien latausaikaa.
7

Lisää hakukoneoptimointi: metatiedot ja hreflang

Luo kieliversiokohtaiset sivuotsikot ja kuvaukset generateMetadatalla. Lisää hreflang-tunnisteille alternates.languages, jotta hakukoneet löytävät jokaisen sivun kaikki kieliversiot.

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:issä koonnit voivat luoda localhost-osoitteen kanoniseksi URL-osoitteeksi, jos metadataBasea ei ole asetettu. Aseta juuriasettelun metadataBase aina tuotantoverkkotunnukseesi.
8

Käsittele virhe- ja ei löydy -sivut

error.tsx ja not-found.tsx tarvitsevat erityiskäsittelyn, koska ne voivat hahmontua tavallisen kieliversioasettelun ulkopuolella. Juuren not-found.tsx tarvitsee oman i18n-tarjoajansa näyttääkseen lokalisoidut virheilmoitukset.

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 hahmontaa lokalisoidun 404-sivusi vain, kun koodisi kutsuu notFound()-funktiota eksplisiittisesti. Tuntemattomat reitit, joilla ei ole vastaavaa sivua, näyttävät Next.js:n oletusarvoisen 404-sivun eivätkä lokalisoitua versiotasi.
9

Automatisoi käännökset

Kun i18n on otettu käyttöön, käännä sanomatiedostosi tekoälyllä suoraan IDE-ympäristöstäsi tai käytä i18n Agent:in CLI:tä CI/CD-putkessasi automatisoimaan käännös jokaisen julkaisun yhteydessä.

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)
Käytä next-intl-localechainia älykkäisiin varakieliin — pt-BR-käyttäjä näkee pt-PT-käännökset englantiin siirtymisen sijaan, kun Brasilian portugali ei ole saatavilla.

Automatisoi käännöslaatu

Löydä puuttuvat avaimet ja rikkoutuneet paikkamerkit i18n-validate:lla ennen julkaisua. Testaa käyttöliittymää tekaistuilla käännöksillä i18n-pseudo:n avulla ennen oikeiden käännösten valmistumista.

Avoimen lähdekoodin työkalut Next.js i18n:ään

Nämä avoimen lähdekoodin paketit ratkaisevat Next.js:n kansainvälistämistyönkulkujen yleisiä ongelmia.

next-intl-localechain

Tavallinen next-intl siirtyy käännöksen puuttuessa suoraan oletuskieliversioosi. Brasilian portugalin käyttäjä näkee englannin täysin käyttökelpoisten pt-PT-käännösten sijaan. next-intl-localechain lisää älykkäät varakieliketjut — se syväyhdistää toisiinsa liittyvien kieliversioiden käännökset, jotta alueelliset käyttäjät näkevät aina lähimmän saatavilla olevan käännöksen.

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'
}));
Syväyhdistää kieliversioketjujen käännökset automaattisesti
Sisäänrakennetut ketjut portugalille, espanjalle, ranskalle, saksalle ja muille kielille
Ohittaa puuttuvat sanomatiedostot hallitusti ilman virheitä
Yhden rivin käyttöönotto — ympäröi nykyisen getRequestConfigisi
Näytä GitHub:issa

@i18n-agent/cli

Komentorivityökalu Next.js-sanomatiedostojen kääntämiseen poistumatta päätteestä. Käännä tiedostot suoraan, tarkista työn tila ja lataa tulokset. Toimii CI/CD-putkissa API-avaintodennuksella täysin automatisoituja lokalisointityönkulkuja varten.

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
Käännä JSON-, YAML- ja PO-tiedostoja sekä muita i18n-tiedostomuotoja päätteestä
Valmis CI/CD-käyttöön — automatisoitujen putkien todennus ympäristömuuttujalla
Seuraa työn tilaa, jatka epäonnistuneita töitä ja lataa tulokset
Koneellisesti luettava JSON-tuloste komentosarjoihin ja automaatioon
Näytä GitHub:issa

Tavalliset sudenkuopat

"Unable to find next-intl locale"

Middleware ei vastannut pyyntöä. Tarkista: onko middleware.ts projektin juuressa? Jättääkö matcher-malli staattiset tiedostot oikein pois? Sisältyykö kieliversio reititysmääritykseesi?

Odottamaton dynaaminen hahmontaminen

setRequestLocale(locale) puuttuu sivulta tai asettelusta. Ilman sitä next-intl tunnistaa kieliversion otsakkeista tai evästeistä, mikä pakottaa dynaamisen hahmontamisen ja estää staattisen luonnin.

Rinnakkaisreitit rikkoutuvat i18n:n kanssa

Rinnakkaisreiteillä (@modal) ja sieppaavilla reiteillä ((.)photo) on tunnettuja yhteensopivuusongelmia dynaamisen [locale]-segmentin kanssa. Käytä näissä edistyneissä reititysmalleissa kiertotienä middleware-pohjaista reititystä.

Kielen vaihtaminen kadottaa nykyisen reitin

Säilytä kieliversiota vaihtaessasi nykyinen polku usePathname()-funktiolla ja korvaa vain kieliversiosegmentti. Ole tarkkana dynaamisten reittiparametrien kanssa — ne on ratkaistava uudelleen uudelle kieliversiolle.

Suositeltu tiedostorakenne

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

Kokeile i18n Agent:ia nyt

Pudota käännöstiedostosi tähän

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

tai valitse napsauttamalla

Kohdekielet

Rekisteröitymistä ei tarvitaVälitön arvio

Varakieliketju next-intl-localechainilla

Kun alueellisesta kieliversiosta, kuten pt-BR:stä, puuttuu käännösavain, next-intl siirtyy suoraan oletuskieliversioon eikä tarkista ensin pääkieliversiota 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`),
});

Katso varakielioppaastamme kaikki tuetut ohjelmistokehykset ja 75 sisäänrakennettua ketjua. Learn more →

Usein kysytyt kysymykset