Skip to main content

Panduan Lengkap Pengantarabangsaan Next.js

Sediakan next-intl dengan App Router, konfigurasikan penghalaan bahasa, dan automatikkan terjemahan dengan AI.

1

Pasang next-intl

next-intl ialah satu pakej yang mengendalikan penghalaan bahasa, pemuatan mesej, dan cangkuk terjemahan untuk App Router Next.js.

Terminal
npm install next-intl
Mengapa next-intl, bukan next-i18next? next-intl dibina untuk App Router dan komponen pelayan. next-i18next direka untuk Pages Router dan mempunyai sokongan App Router yang terhad.
2

Cipta Konfigurasi Permintaan i18n

Cipta dua fail: src/i18n/request.ts untuk memuatkan mesej dan src/i18n/routing.ts untuk takrif bahasa. Fail ini mengkonfigurasi cara next-intl menyelesaikan mesej dan laluan.

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 (penghimpun lalai dalam Next.js 15) memerlukan experimental.turbo.resolveAlias dalam next.config.js. Tanpanya, anda akan mendapat ralat "Couldn't find next-intl config file".
3

Konfigurasikan Middleware

Tambahkan middleware.ts untuk mengendalikan pengesanan bahasa, penulisan semula URL, dan pengalihan. Middleware memintas setiap permintaan dan memastikan bahasa yang betul digunakan.

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 MESTI berada dalam direktori akar projek, bukan dalam src/. Ini ialah kesilapan konfigurasi next-intl yang paling biasa.
4

Sediakan Struktur Folder [locale]

Pindahkan laluan aplikasi ke dalam app/[locale]/. Tambahkan generateStaticParams untuk menjana halaman bagi setiap bahasa semasa binaan. Ini menghasilkan struktur URL /en/about, /de/about, dan seterusnya.

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

export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }));
}
Anda MESTI memanggil setRequestLocale(locale) dalam setiap page.tsx dan layout.tsx yang menggunakan terjemahan. Tanpanya, Next.js beralih kepada pemaparan dinamik dan prestasi binaan menurun dengan ketara.
5

Kemas Kini Root Layout

Muatkan mesej dengan getMessages() dan teruskan kepada NextIntlClientProvider dalam root layout bahasa. Tetapkan atribut lang HTML daripada parameter bahasa.

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 memerlukan prop locale yang jelas. Jika ditinggalkan, komponen klien mengalami ralat halus yang sukar dinyahpepijat.
6

Gunakan Terjemahan dalam Komponen

Komponen pelayan menggunakan getTranslations (tidak segerak, await). Komponen klien menggunakan useTranslations (cangkuk). Pilih berdasarkan tempat komponen dipaparkan—komponen pelayan menghalang terjemahan daripada memasuki bundle JavaScript sepenuhnya.

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')} />;
}
Pilih komponen pelayan untuk kandungan terjemahan. Komponen tersebut menghalang rentetan terjemahan daripada memasuki bundle JavaScript klien, lalu mengurangkan masa muat pengguna.
7

Tambahkan SEO: Metadata dan Hreflang

Gunakan generateMetadata untuk menghasilkan tajuk dan penerangan halaman khusus bahasa. Tambahkan alternates.languages untuk teg hreflang supaya enjin carian menemui semua versi bahasa setiap halaman.

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}`])
      ),
    },
  };
}
Dalam Vercel, binaan boleh menghasilkan localhost sebagai URL kanonik jika metadataBase tidak ditetapkan. Sentiasa tetapkan metadataBase dalam root layout kepada domain pengeluaran anda.
8

Kendalikan Halaman Ralat dan Tidak Ditemui

error.tsx dan not-found.tsx memerlukan pengendalian khusus kerana boleh dipaparkan di luar layout bahasa biasa. Root not-found.tsx memerlukan persediaan penyedia i18n sendiri untuk memaparkan mesej ralat setempat.

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 hanya memaparkan halaman 404 setempat apabila notFound() dipanggil secara jelas dalam kod. Laluan tidak dikenali tanpa halaman yang sepadan memaparkan 404 lalai Next.js, bukan versi setempat anda.
9

Automatikkan Terjemahan

Selepas persediaan i18n selesai, terjemah fail mesej menggunakan AI terus daripada IDE atau gunakan CLI i18n Agent dalam saluran CI/CD untuk terjemahan automatik pada setiap penggunaan.

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)
Gunakan next-intl-localechain untuk sandaran bahasa pintar—pengguna pt-BR akan melihat terjemahan pt-PT dan bukannya beralih kepada bahasa Inggeris apabila Portugis Brazil tiada.

Automatikkan Kualiti Terjemahan

Kesan kekunci hilang dan ruang letak rosak sebelum dikeluarkan dengan i18n-validate. Uji UI dengan terjemahan palsu menggunakan i18n-pseudo sebelum terjemahan sebenar tersedia.

Alat Sumber Terbuka untuk Next.js i18n

Pakej sumber terbuka ini menyelesaikan masalah umum dalam aliran kerja pengantarabangsaan Next.js.

next-intl-localechain

next-intl standard terus beralih kepada bahasa lalai apabila terjemahan hilang. Pengguna Portugis Brazil melihat bahasa Inggeris, bukan terjemahan pt-PT yang masih sesuai. next-intl-localechain menambahkan rantaian sandaran pintar—sistem menggabungkan terjemahan secara mendalam daripada bahasa berkaitan supaya pengguna serantau sentiasa melihat terjemahan tersedia yang paling hampir.

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'
}));
Menggabungkan terjemahan secara mendalam merentas rantaian bahasa secara automatik
Rantaian terbina dalam untuk bahasa Portugis, Sepanyol, Perancis, Jerman, dan banyak lagi
Melangkau fail mesej yang hilang dengan lancar tanpa ralat
Persediaan satu baris—membalut getRequestConfig sedia ada
Lihat di GitHub

@i18n-agent/cli

Alat baris perintah untuk menterjemah fail mesej Next.js tanpa meninggalkan terminal. Terjemah fail secara langsung, semak keadaan tugas, dan muat turun hasil. Berfungsi dalam saluran CI/CD dengan pengesahan kekunci API untuk aliran kerja penyetempatan automatik sepenuhnya.

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
Terjemah JSON, YAML, PO, dan format fail i18n lain daripada terminal
Sedia untuk CI/CD—sahkan melalui pemboleh ubah persekitaran untuk saluran automatik
Jejaki keadaan tugas, sambung semula tugas yang gagal, dan muat turun hasil
Output JSON yang boleh dibaca mesin untuk penskripan dan automasi
Lihat di GitHub

Kesilapan Umum

"Unable to find next-intl locale"

Middleware tidak sepadan dengan permintaan. Periksa: adakah middleware.ts berada pada akar projek? Adakah corak matcher mengecualikan fail statik dengan betul? Adakah bahasa disenaraikan dalam konfigurasi penghalaan?

Pemaparan Dinamik yang Tidak Dijangka

setRequestLocale(locale) tiada dalam halaman atau layout. Tanpanya, next-intl menggunakan pengepala/kuki untuk mengesan bahasa, lalu memaksa pemaparan dinamik dan menghalang penjanaan statik.

Laluan Selari Rosak dengan i18n

Laluan selari (@modal) dan laluan pemintas ((.)photo) diketahui tidak serasi dengan segmen dinamik [locale]. Gunakan penghalaan berasaskan middleware sebagai penyelesaian sementara untuk corak penghalaan lanjutan ini.

Penukaran Bahasa Kehilangan Laluan Semasa

Apabila beralih bahasa, kekalkan pathname semasa dengan usePathname() dan gantikan hanya segmen bahasa. Berhati-hati dengan parameter laluan dinamik—parameter tersebut perlu diselesaikan semula untuk bahasa baharu.

Struktur Fail yang Disyorkan

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

Cuba i18n Agent Sekarang

Lepaskan fail terjemahan anda di sini

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

atau klik untuk semak imbas

Bahasa sasaran

Tidak perlu mendaftarAnggaran serta-merta

Sandaran Bahasa dengan next-intl-localechain

Apabila kekunci terjemahan tiada dalam bahasa serantau seperti pt-BR, next-intl terus beralih kepada bahasa lalai dan bukannya memeriksa bahasa induk pt terlebih dahulu.

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`),
});

Lihat Panduan Sandaran Bahasa kami untuk senarai lengkap rangka kerja yang disokong dan 75 rantaian terbina dalam. Learn more →

Soalan Lazim