Next.js Internationalisierung – Vollständiger Leitfaden: next-intl Best Practices

Letztes Jahr habe ich ein Next.js-Projekt übernommen, das Mehrsprachigkeit unterstützen musste. Beim Anblick der verschiedenen i18n-Einstellungen in der Konfiguration war ich zunächst etwas überfordert. Nach stundenlangem Durchforsten der Dokumentation wurde klar: App Router und Pages Router verfolgen bei der Internationalisierung völlig unterschiedliche Ansätze. Eine Woche später war next-intl eingerichtet – und unterwegs habe ich einige typische Fallen kennengelernt.
In diesem Artikel geht es um Internationalisierung in Next.js – insbesondere darum, wie Sie mit next-intl im App Router elegant Mehrsprachigkeit umsetzen.
Warum next-intl?
Vielleicht fragen Sie sich: Hat Next.js nicht eingebaute Internationalisierung? Tatsächlich bot der Pages Router früher native i18n-Routing-Unterstützung. Im App Router wurde diese Funktion entfernt.
Die offizielle Empfehlung lautet: Drittanbieter-Bibliotheken nutzen. next-intl ist dabei eine der beliebtesten Optionen.
Vorteile von next-intl:
- Native App-Router-Unterstützung – speziell für den App Router entwickelt, sehr angenehm in der Handhabung
- Typsicherheit – in Kombination mit TypeScript lassen sich Übersetzungstexte typprüfen
- Flexible Routing-Strategien – Unterpfade, Domains, Cookies und weitere Sprachwechsel-Varianten
- Umfangreiche Funktionen – Pluralisierung, Datums- und Zahlenformatierung, Rich Text und mehr
- Gute Performance – Server-Component-freundlich, unterstützt statisches Rendering
Im Vergleich zu anderen Lösungen ist die Dokumentation von next-intl ebenfalls gut verständlich – der Einstieg fällt weniger schwer.
Grundkonfiguration: Von null an starten
1. Abhängigkeiten installieren
Zuerst installieren Sie next-intl:
npm install next-intl
# oder
pnpm add next-intl
# oder
yarn add next-intl
2. Übersetzungsdateien anlegen
Erstellen Sie im Projektroot einen Ordner messages (alternativ locales oder ein anderer Name) und legen Sie pro Sprache eine JSON-Datei an:
messages/
├── en.json
├── zh.json
└── ja.json
messages/zh.json:
{
"HomePage": {
"title": "欢迎来到我的网站",
"description": "这是一个支持多语言的 Next.js 应用"
},
"Navigation": {
"home": "首页",
"about": "关于",
"contact": "联系我们"
}
}
messages/en.json:
{
"HomePage": {
"title": "Welcome to My Website",
"description": "This is a multilingual Next.js application"
},
"Navigation": {
"home": "Home",
"about": "About",
"contact": "Contact Us"
}
}
Eine verschachtelte Struktur ist nicht zwingend – ich finde aber, dass die Gruppierung nach Seite oder Komponente die Verwaltung deutlich erleichtert.
3. i18n.ts konfigurieren
Erstellen Sie i18n.ts (oder i18n/config.ts) und definieren Sie die unterstützten Sprachen:
import { getRequestConfig } from 'next-intl/server';
export default getRequestConfig(async ({ locale }) => ({
messages: (await import(`./messages/${locale}.json`)).default
}));
Diese Konfiguration teilt next-intl mit, wo die Übersetzungsdateien liegen. Der Parameter locale wird automatisch aus der URL extrahiert.
4. Middleware erstellen
Erstellen Sie im Projektroot middleware.ts – das ist der Schlüssel für mehrsprachiges Routing:
import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
// Unterstützte Sprachen
locales: ['en', 'zh', 'ja'],
// Standardsprache
defaultLocale: 'zh',
// Standardsprache immer in der URL anzeigen?
localePrefix: 'as-needed'
});
export const config = {
// Alle Pfade außer api, _next/static, _next/image, favicon.ico
matcher: ['/', '/(zh|en|ja)/:path*', '/((?!api|_next|_next/static|_next/image|favicon.ico).*)']
};
Optionen für localePrefix:
'always'– alle Sprachen mit Präfix, auch die Standardsprache (/zh/about,/en/about)'as-needed'– Standardsprache ohne Präfix (/about,/en/about)'never'– kein Sprachpräfix in der URL (Sprache wird anders erkannt, z. B. per Domain)
Ich nutze meist 'as-needed' – für chinesische Nutzer freundlich und die URL wirkt aufgeräumter.
5. app-Verzeichnisstruktur anpassen
Das ist der entscheidende Schritt: Alle Routen gehören unter die dynamische Route [locale].
Vorher:
app/
├── page.tsx
├── about/
│ └── page.tsx
└── layout.tsx
Nachher:
app/
├── [locale]/
│ ├── page.tsx
│ ├── about/
│ │ └── page.tsx
│ └── layout.tsx
└── layout.tsx (optional, für globale Konfiguration)
6. Root-Layout konfigurieren
In app/[locale]/layout.tsx richten Sie die Sprache ein:
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';
import { notFound } from 'next/navigation';
const locales = ['en', 'zh', 'ja'];
export function generateStaticParams() {
return locales.map((locale) => ({ locale }));
}
export default async function LocaleLayout({
children,
params: { locale }
}: {
children: React.ReactNode;
params: { locale: string };
}) {
// Prüfen, ob die Sprache unterstützt wird
if (!locales.includes(locale)) {
notFound();
}
const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
Beachten Sie generateStaticParams: Bei statischer Generierung teilt diese Funktion Next.js mit, für welche Sprachen Seiten erzeugt werden sollen.
Übersetzungen in Komponenten nutzen
Nach der Konfiguration können Sie in Komponenten Übersetzungen verwenden.
In Server Components
import { useTranslations } from 'next-intl';
export default function HomePage() {
const t = useTranslations('HomePage');
return (
<div>
<h1>{t('title')}</h1>
<p>{t('description')}</p>
</div>
);
}
Der Parameter von useTranslations ist der Namespace in der Übersetzungsdatei (der äußerste Key). Ohne Parameter können Sie den vollen Pfad nutzen, z. B. t('HomePage.title').
In Client Components
In Client Components funktioniert es genauso:
'use client';
import { useTranslations } from 'next-intl';
export default function Navigation() {
const t = useTranslations('Navigation');
return (
<nav>
<a href="/">{t('home')}</a>
<a href="/about">{t('about')}</a>
<a href="/contact">{t('contact')}</a>
</nav>
);
}
Das ist der elegante Teil an next-intl – Server und Client Components nutzen dieselbe API.
Mehrsprachiges Routing
Aktuelle Sprache ermitteln
import { useLocale } from 'next-intl';
export default function LanguageSwitcher() {
const locale = useLocale();
return <div>Current language: {locale}</div>;
}
Sprachumschalter erstellen
Jede mehrsprachige Website braucht das:
'use client';
import { useLocale } from 'next-intl';
import { usePathname, useRouter } from 'next/navigation';
export default function LanguageSwitcher() {
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
const switchLanguage = (newLocale: string) => {
// Sprachsegment im Pfad ersetzen
const newPath = pathname.replace(`/${locale}`, `/${newLocale}`);
router.push(newPath);
};
return (
<select value={locale} onChange={(e) => switchLanguage(e.target.value)}>
<option value="zh">中文</option>
<option value="en">English</option>
<option value="ja">日本語</option>
</select>
);
}
Es gibt allerdings eine kleine Schwäche: Steht der Nutzer auf der Standardsprache (z. B. Chinesisch) unter /about, soll der Wechsel nach Englisch /en/about ergeben. Der obige Code braucht eine Anpassung:
const switchLanguage = (newLocale: string) => {
// Aktuelles Sprachpräfix entfernen
let path = pathname;
if (pathname.startsWith(`/${locale}`)) {
path = pathname.substring(locale.length + 1);
}
// Neues Sprachpräfix hinzufügen (außer Standardsprache bei as-needed)
const newPath = newLocale === 'zh' ? path : `/${newLocale}${path}`;
router.push(newPath);
};
Link-Komponente nutzen
next-intl bietet eine erweiterte Link-Komponente, die Sprachpräfixe automatisch handhabt:
import { Link } from '@/navigation'; // vorher konfigurieren
<Link href="/about">
{t('about')}
</Link>
Konfiguration in navigation.ts:
import { createSharedPathnamesNavigation } from 'next-intl/navigation';
export const locales = ['en', 'zh', 'ja'] as const;
export const localePrefix = 'as-needed';
export const { Link, redirect, usePathname, useRouter } =
createSharedPathnamesNavigation({ locales, localePrefix });
Die exportierten Link-, useRouter- und weiteren Hilfsmittel verarbeiten Sprachpfade automatisch.
Erweiterte Funktionen
1. Übersetzungen mit Parametern
Oft müssen Variablen in Übersetzungen eingefügt werden – next-intl unterstützt das so:
messages/zh.json:
{
"welcome": "欢迎回来,{username}!",
"items": "你有 {count} 个新消息"
}
Verwendung:
const t = useTranslations();
<p>{t('welcome', { username: 'John' })}</p>
<p>{t('items', { count: 5 })}</p>
2. Pluralisierung
Pluralregeln unterscheiden sich je nach Sprache – next-intl bietet dafür passende APIs:
messages/en.json:
{
"messages": {
"one": "You have {count} message",
"other": "You have {count} messages"
}
}
Verwendung:
t('messages', { count: 1 }) // "You have 1 message"
t('messages', { count: 5 }) // "You have 5 messages"
Chinesisch kennt keine Pluralform – Sie können es so schreiben:
messages/zh.json:
{
"messages": "你有 {count} 条消息"
}
3. Datums- und Zahlenformatierung
next-intl stellt dedizierte Formatierungsfunktionen bereit:
import { useFormatter } from 'next-intl';
export default function DateExample() {
const format = useFormatter();
const now = new Date();
return (
<div>
<p>{format.dateTime(now, { dateStyle: 'full' })}</p>
{/* Chinesisch: 2025年12月25日星期三 */}
{/* Englisch: Wednesday, December 25, 2025 */}
<p>{format.number(1234567.89, { style: 'currency', currency: 'CNY' })}</p>
{/* Chinesisch: ¥1,234,567.89 */}
{/* Englisch: CN¥1,234,567.89 */}
</div>
);
}
4. Rich-Text-Übersetzungen
Manchmal enthalten Übersetzungen HTML-Tags oder React-Komponenten:
messages/zh.json:
{
"richText": "我同意<terms>服务条款</terms>和<privacy>隐私政策</privacy>"
}
Verwendung:
import { useTranslations } from 'next-intl';
export default function Agreement() {
const t = useTranslations();
return (
<p>
{t.rich('richText', {
terms: (chunks) => <a href="/terms">{chunks}</a>,
privacy: (chunks) => <a href="/privacy">{chunks}</a>
})}
</p>
);
}
Best Practices für Übersetzungsdateien
Mit wachsendem Projekt werden Übersetzungsdateien schwerer zu pflegen. Hier einige praktische Tipps:
1. Nach Funktionsmodulen aufteilen
Packen Sie nicht alles in eine große JSON-Datei – teilen Sie nach Seite oder Feature auf:
messages/
├── zh/
│ ├── common.json # Allgemeine Texte (Buttons, Fehlermeldungen)
│ ├── home.json # Startseite
│ ├── about.json # Über-Seite
│ └── auth.json # Authentifizierung
├── en/
│ ├── common.json
│ ├── home.json
│ ├── about.json
│ └── auth.json
In i18n.ts zusammenführen:
import { getRequestConfig } from 'next-intl/server';
export default getRequestConfig(async ({ locale }) => {
const common = (await import(`./messages/${locale}/common.json`)).default;
const home = (await import(`./messages/${locale}/home.json`)).default;
const about = (await import(`./messages/${locale}/about.json`)).default;
const auth = (await import(`./messages/${locale}/auth.json`)).default;
return {
messages: {
common,
home,
about,
auth
}
};
});
2. TypeScript-Typsicherheit
Besonders hilfreich: Typen für Übersetzungsdateien definieren, um Tippfehler zu vermeiden:
types/i18n.ts:
import zh from '@/messages/zh.json';
type Messages = typeof zh;
declare global {
interface IntlMessages extends Messages {}
}
TypeScript konfigurieren (tsconfig.json):
{
"compilerOptions": {
"types": ["./types/i18n"]
}
}
Bei t('xxx') meldet TypeScript fehlende Keys – sehr praktisch!
3. Gemeinsame Übersetzungen extrahieren
Texte wie „Speichern“, „Abbrechen“, „Löschen“ tauchen überall auf – besser zentral verwalten:
messages/zh/common.json:
{
"actions": {
"save": "保存",
"cancel": "取消",
"delete": "删除",
"confirm": "确认",
"edit": "编辑"
},
"status": {
"success": "操作成功",
"error": "操作失败",
"loading": "加载中..."
}
}
Verwendung:
const t = useTranslations('common.actions');
<button>{t('save')}</button>
4. Übersetzungs-Tools nutzen
Bei großen Projekten wird manuelles JSON-Pflegen mühsam. Mögliche Tools:
- Tolgee – Open-Source-Übersetzungsplattform mit Live-Bearbeitung
- Localazy – automatisierte Übersetzungs-Workflows
- i18n Ally (VSCode-Erweiterung) – Übersetzungen direkt im Editor verwalten
Ich nutze vor allem i18n Ally – beim Codieren sehe ich Übersetzungen direkt und kann sie schnell anpassen.
5. Fehlende Übersetzungen behandeln
In der Entwicklung fehlen oft noch Übersetzungen für einzelne Sprachen. Fallback-Logik konfigurieren:
// i18n.ts
export default getRequestConfig(async ({ locale }) => {
const messages = (await import(`./messages/${locale}.json`)).default;
const fallback = locale !== 'zh'
? (await import(`./messages/zh.json`)).default
: {};
return {
messages: {
...fallback,
...messages
}
};
});
Fehlt eine englische Übersetzung, greift automatisch Chinesisch als Fallback.
Performance-Optimierung
1. Code-Splitting
Bei großen Übersetzungsdateien lazy loading nutzen:
// Nur bei Bedarf laden
export default function AdminPage() {
const t = useTranslations('admin'); // nur admin-Namespace
// ...
}
2. Statische Generierung
Für selten ändernde Seiten verbessert statisches Rendering die Performance deutlich:
// app/[locale]/about/page.tsx
export const dynamic = 'force-static';
export function generateStaticParams() {
return [
{ locale: 'zh' },
{ locale: 'en' },
{ locale: 'ja' }
];
}
3. Übersetzungen vorladen
Für Above-the-fold-Inhalte Übersetzungen serverseitig vorladen:
import { getTranslations } from 'next-intl/server';
// Serverseitig vorladen
export default async function Home() {
const t = await getTranslations('HomePage');
return <h1>{t('title')}</h1>;
}
Häufige Probleme und Lösungen
1. Sprachwechsel bei dynamischen Routen
Bei dynamischen Routen (z. B. /blog/[slug]) muss der Slug beim Sprachwechsel erhalten bleiben:
const switchLanguage = (newLocale: string) => {
const segments = pathname.split('/').filter(Boolean);
// Altes Sprachpräfix entfernen
if (['zh', 'en', 'ja'].includes(segments[0])) {
segments.shift();
}
// Neues Sprachpräfix hinzufügen (falls nötig)
if (newLocale !== 'zh' || localePrefix === 'always') {
segments.unshift(newLocale);
}
router.push('/' + segments.join('/'));
};
2. SEO-Optimierung
Bei mehrsprachigen Websites verdient SEO besondere Aufmerksamkeit:
// app/[locale]/layout.tsx
export async function generateMetadata({ params: { locale } }) {
const t = await getTranslations({ locale, namespace: 'metadata' });
return {
title: t('title'),
description: t('description'),
alternates: {
canonical: `https://example.com/${locale}`,
languages: {
'zh-CN': 'https://example.com/zh',
'en-US': 'https://example.com/en',
'ja-JP': 'https://example.com/ja'
}
}
};
}
3. Spracherkennung
Beim ersten Besuch die Nutzersprache automatisch erkennen:
// middleware.ts
import createMiddleware from 'next-intl/middleware';
import { NextRequest } from 'next/server';
const intlMiddleware = createMiddleware({
locales: ['en', 'zh', 'ja'],
defaultLocale: 'zh',
localeDetection: true // automatische Erkennung aktivieren
});
export default function middleware(request: NextRequest) {
return intlMiddleware(request);
}
next-intl wählt die Sprache anhand des Accept-Language-Headers.
4. Sprachpräferenz speichern
Nach manueller Sprachwahl sollte die Wahl gemerkt werden:
// Per Cookie speichern
const switchLanguage = (newLocale: string) => {
document.cookie = `NEXT_LOCALE=${newLocale}; path=/; max-age=31536000`;
router.push(newPath);
};
Die next-intl-Middleware liest dieses Cookie automatisch aus.
Praxisbeispiel: vollständiges i18n-Projekt
Zum Abschluss die wichtigsten Codeausschnitte aus einem kleinen Projekt, das ich umgesetzt habe:
Projektstruktur:
├── app/
│ ├── [locale]/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── blog/
│ │ └── [slug]/
│ │ └── page.tsx
├── components/
│ ├── LanguageSwitcher.tsx
│ └── Navigation.tsx
├── messages/
│ ├── zh/
│ │ ├── common.json
│ │ └── blog.json
│ ├── en/
│ │ ├── common.json
│ │ └── blog.json
├── i18n.ts
├── middleware.ts
└── navigation.ts
navigation.ts (Routing-Konfiguration):
import { createSharedPathnamesNavigation } from 'next-intl/navigation';
export const locales = ['zh', 'en'] as const;
export const localePrefix = 'as-needed';
export const { Link, redirect, usePathname, useRouter } =
createSharedPathnamesNavigation({ locales, localePrefix });
components/Navigation.tsx:
'use client';
import { Link } from '@/navigation';
import { useTranslations } from 'next-intl';
import LanguageSwitcher from './LanguageSwitcher';
export default function Navigation() {
const t = useTranslations('common.navigation');
return (
<nav className="flex items-center justify-between p-4">
<div className="flex gap-4">
<Link href="/">{t('home')}</Link>
<Link href="/blog">{t('blog')}</Link>
<Link href="/about">{t('about')}</Link>
</div>
<LanguageSwitcher />
</nav>
);
}
Nach dem Go-live lief der Sprachwechsel sehr flüssig – ohne nennenswerte Probleme.
Fazit
Internationalisierung im Next.js App Router wirkt zunächst komplex – mit next-intl ist sie aber gut beherrschbar:
- Kernkonfiguration: Middleware + i18n.ts +
[locale]-Verzeichnis - Übersetzungen nutzen:
useTranslations-Hook in Server- und Client Components - Routing: Link und Router von next-intl verwenden
- Dateiverwaltung: modular aufteilen + TypeScript-Typsicherheit
- Performance: statische Generierung + Lazy Loading
Ehrlich gesagt wirkte das Setup anfangs verschachtelt – besonders Middleware und dynamische Routen. Nach ein paar Projekten ist es Routine; für i18n-Projekte nutze ich fast immer dieses Muster.
Wenn Sie ein mehrsprachiges Projekt planen oder bereits daran arbeiten, lohnt sich next-intl. Der Lernaufwand zahlt sich langfristig aus.
Referenzen
- next-intl offizielle Dokumentation
- Next.js Internationalisierungsleitfaden
- i18n Ally VSCode-Erweiterung
- Tolgee Übersetzungsplattform
Ich hoffe, dieser Artikel hilft Ihnen bei der Next.js-Internationalisierung!
Next.js Internationalisierung – vollständiger Konfigurationsablauf
Vom Installieren von next-intl bis zur Konfiguration mehrsprachiger Routen und Übersetzungsdateien – Schritt für Schritt
⏱️ Estimated time: 2 hr
- 1
Step 1: next-intl installieren und Grundkonfiguration
Installation:
```bash
npm install next-intl
```
Übersetzungsdateien anlegen:
```
messages/
zh.json
en.json
```
middleware.ts konfigurieren:
```ts
import createMiddleware from 'next-intl/middleware'
import { routing } from './i18n/routing'
export default createMiddleware(routing)
export const config = {
matcher: ['/', '/(zh|en)/:path*']
}
```
app/[locale]/layout.tsx konfigurieren:
```tsx
import { NextIntlClientProvider } from 'next-intl'
import { getMessages } from 'next-intl/server'
export default async function LocaleLayout({
children,
params: { locale }
}) {
const messages = await getMessages()
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
)
}
```
Wichtige Punkte:
• [locale]-Dynamikroute verwenden
• Übersetzungen im Layout bereitstellen
• Middleware für Sprachwechsel konfigurieren - 2
Step 2: Mehrsprachige Routing-Strategie konfigurieren
Strategie 1: Unterpfad (empfohlen)
• URL-Format: /zh/about, /en/about
• Einfache Konfiguration
• SEO-freundlich
Strategie 2: Domain
• URL-Format: zh.example.com, en.example.com
• Mehrere Domains nötig
• Professioneller
Strategie 3: Cookie
• Sprache per Cookie umschalten
• URL ohne Sprachpräfix
• Für einsprachige Nutzer geeignet
Unterpfad konfigurieren:
```ts
// i18n/routing.ts
export const routing = {
locales: ['zh', 'en'],
defaultLocale: 'zh'
}
```
Verwendung:
```tsx
import { useTranslations } from 'next-intl'
export function Page() {
const t = useTranslations('common')
return <h1>{t('title')}</h1>
}
```
Wichtiger Punkt: Wählen Sie die passende Routing-Strategie – für die meisten Projekte reicht der Unterpfad. - 3
Step 3: Übersetzungsdateien verwalten
Übersetzungsdatei anlegen:
```json
// messages/zh.json
{
"common": {
"title": "欢迎",
"description": "这是一个多语言网站"
},
"nav": {
"home": "首页",
"about": "关于"
}
}
```
Übersetzung nutzen:
```tsx
import { useTranslations } from 'next-intl'
export function Page() {
const t = useTranslations('common')
return (
<div>
<h1>{t('title')}</h1>
<p>{t('description')}</p>
</div>
)
}
```
Typsicherheit:
```ts
// i18n/request.ts
import { getRequestConfig } from 'next-intl/server'
export default getRequestConfig(async ({ locale }) => ({
messages: (await import(`../messages/${locale}.json`)).default
}))
```
Wichtige Punkte:
• Verschachtelte Struktur für Übersetzungen
• TypeScript für Typsicherheit
• i18n-Ally-VSCode-Erweiterung für bessere Developer Experience
FAQ
Warum braucht der App Router next-intl?
Pages Router:
• Eingebaute i18n-Routing-Unterstützung
• i18n-Feld in next.config.js konfigurieren
• Automatischer Sprachwechsel
App Router:
• Keine eingebaute i18n-Funktion mehr
• Drittanbieter-Bibliotheken erforderlich
• next-intl ist die beliebteste Wahl
next-intl-Vorteile:
• Native App-Router-Unterstützung
• Typsicherheit
• Flexible Routing-Strategien
• Umfangreiche Funktionen (Plural, Datumsformatierung usw.)
• Gute Performance
Empfehlung: Bei App Router next-intl bevorzugen.
Welche Routing-Strategien bietet next-intl?
Strategie 1: Unterpfad (empfohlen)
• URL-Format: /zh/about, /en/about
• Einfache Konfiguration
• SEO-freundlich
• Für die meisten Projekte geeignet
Strategie 2: Domain
• URL-Format: zh.example.com, en.example.com
• Mehrere Domains nötig
• Professioneller
• Für große Projekte
Strategie 3: Cookie
• Sprache per Cookie umschalten
• URL ohne Sprachpräfix
• Für einsprachige Nutzer
• Komplexere Konfiguration
Auswahl:
• Die meisten Projekte → Unterpfad
• Große Projekte → Domain
• Spezielle Anforderungen → Cookie
Wichtiger Punkt: Für die meisten Projekte reicht der Unterpfad.
Wie konfiguriert man next-intl?
```bash
npm install next-intl
```
Übersetzungsdateien anlegen:
```
messages/
zh.json
en.json
```
middleware.ts konfigurieren:
```ts
import createMiddleware from 'next-intl/middleware'
import { routing } from './i18n/routing'
export default createMiddleware(routing)
export const config = {
matcher: ['/', '/(zh|en)/:path*']
}
```
app/[locale]/layout.tsx konfigurieren:
```tsx
import { NextIntlClientProvider } from 'next-intl'
import { getMessages } from 'next-intl/server'
export default async function LocaleLayout({
children,
params: { locale }
}) {
const messages = await getMessages()
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
)
}
```
Wichtige Punkte:
• [locale]-Dynamikroute verwenden
• Übersetzungen im Layout bereitstellen
• Middleware für Sprachwechsel konfigurieren
Wie verwaltet man Übersetzungsdateien?
```json
// messages/zh.json
{
"common": {
"title": "欢迎",
"description": "这是一个多语言网站"
},
"nav": {
"home": "首页",
"about": "关于"
}
}
```
Übersetzung nutzen:
```tsx
import { useTranslations } from 'next-intl'
export function Page() {
const t = useTranslations('common')
return (
<div>
<h1>{t('title')}</h1>
<p>{t('description')}</p>
</div>
)
}
```
Typsicherheit:
```ts
// i18n/request.ts
import { getRequestConfig } from 'next-intl/server'
export default getRequestConfig(async ({ locale }) => ({
messages: (await import(`../messages/${locale}.json`)).default
}))
```
Wichtige Punkte:
• Verschachtelte Struktur für Übersetzungen
• TypeScript für Typsicherheit
• i18n-Ally-VSCode-Erweiterung für bessere Developer Experience
Empfehlung: Übersetzungsdateien nach Funktionsmodulen organisieren, keine zu großen Einzeldateien.
Welche Funktionen unterstützt next-intl?
• Übersetzungstexte (t-Funktion)
• Pluralisierung
• Datumsformatierung
• Zahlenformatierung
• Rich-Text-Unterstützung
Beispiel:
```tsx
import { useTranslations, useFormatter } from 'next-intl'
export function Page() {
const t = useTranslations('common')
const format = useFormatter()
return (
<div>
<h1>{t('title')}</h1>
<p>{format.dateTime(new Date(), { dateStyle: 'long' })}</p>
<p>{format.number(1234.56, { style: 'currency', currency: 'USD' })}</p>
</div>
)
}
```
Vorteile:
• Umfangreiche Funktionen
• Typsicherheit
• Gute Performance
• Server-Component-freundlich
Empfehlung: next-intl-Funktionen voll nutzen, um die Nutzererfahrung zu verbessern.
Wie implementiert man den Sprachwechsel?
```tsx
import { Link } from '@/i18n/navigation'
<Link href="/about" locale="en">
English
</Link>
<Link href="/about" locale="zh">
中文
</Link>
```
useRouter nutzen:
```tsx
'use client'
import { useRouter, usePathname } from '@/i18n/navigation'
export function LanguageSwitcher() {
const router = useRouter()
const pathname = usePathname()
const switchLanguage = (locale: string) => {
router.replace(pathname, { locale })
}
return (
<button onClick={() => switchLanguage('en')}>
English
</button>
)
}
```
Wichtige Punkte:
• Link und useRouter von next-intl verwenden
• Aktuellen Pfad beibehalten, nur Sprache wechseln
• Gute Nutzererfahrung
Empfehlung: Sprachumschalter in Navigation oder Footer platzieren.
11 Min. Lesezeit · Veröffentlicht am: 25. Dez. 2025 · Aktualisiert am: 14. Juli 2026
Next.js Komplettleitfaden
Wenn du über die Suche hier gelandet bist, kommst du am schnellsten weiter, indem du zum vorherigen oder nächsten Beitrag dieser Serie springst.
Vorheriger
Next.js OAuth-Login in der Praxis: Google, GitHub und WeChat Schritt für Schritt
Vom OAuth-Prinzip bis zur Konfiguration: mit der Paket-Abhol-Analogie den Ablauf verstehen und NextAuth.js für Google, GitHub und WeChat einrichten – inklusive Fehlerbehebung
Teil 14 von 51
Nächster
Next.js Internationalisierung und statische Generierung: SSG-Mehrsprachen-Website in der Praxis
Vom Build-Fehler bis zur Performance-Optimierung: Schritt für Schritt mehrsprachige statische Generierung mit dem App Router – inkl. Codebeispielen, generateStaticParams und Build-Zeit-Tipps.
Teil 16 von 51
Ähnliche Beiträge
Next.js App Router Einstieg: Kernkonzepte und Grundlagen im Überblick

Next.js App Router Einstieg: Kernkonzepte und Grundlagen im Überblick
Next.js 15 in der Praxis: Wie ich an einem Wochenende ein produktionsreifes Blog-System aufgebaut habe


Kommentare
Melde dich mit GitHub an, um einen Kommentar zu hinterlassen