Schnelle Antwort
Um Internationalisierung (i18n) zu Next.js 15 hinzuzufügen, nutzen Sie next-intl mit App Router. Installieren mit npm install next-intl, einen [locale] Ordner in Ihrem App-Verzeichnis erstellen, Middleware für Locale-Erkennung konfigurieren und getTranslations() in Server Components oder useTranslations() in Client Components verwenden.
Was sich in Next.js 15 wirklich geändert hat
Mit Server Components können Übersetzungen komplett auf dem Server bleiben. Der Client bekommt nur das gerenderte HTML.
| Was Sie bekommen | Pages Router | App Router |
|---|---|---|
| Server-gerenderte Übersetzungen | Halbwegs | Ja, richtig |
| Streaming | Umständlich | Eingebaut |
| Verschachtelte Layouts pro Locale | Manuelle Arbeit | Funktioniert einfach |
| Bundle-Größe Übersetzungen | Alle Sprachen | Nur aktuelle Sprache |
Einrichtung
Installation
Terminalnpm install next-intl
Ordnerstruktur
/messages
/de.json
/en.json
/es.json
/app
/[locale]
/layout.tsx
/page.tsx
/middleware.ts
Konfigurationsdateien
i18n/config.ts:
TypeScriptexport const locales = ['en', 'de', 'es', 'fr', 'ja'] as const; export type Locale = (typeof locales)[number]; export const defaultLocale: Locale = 'en';
Middleware
TypeScript1import createMiddleware from 'next-intl/middleware'; 2import { locales, defaultLocale } from './i18n/config'; 3 4export default createMiddleware({ 5 locales, 6 defaultLocale, 7 localePrefix: 'always' 8}); 9 10export const config = { 11 matcher: ['/((?!api|_next|.*\\..*).*)'] 12};
Layout Setup
TypeScript1import { NextIntlClientProvider } from 'next-intl'; 2import { getMessages } from 'next-intl/server'; 3 4export default async function LocaleLayout({ 5 children, 6 params: { locale } 7}) { 8 const messages = await getMessages(); 9 10 return ( 11 <html lang={locale}> 12 <body> 13 <NextIntlClientProvider messages={messages}> 14 {children} 15 </NextIntlClientProvider> 16 </body> 17 </html> 18 ); 19}
Übersetzungen verwenden
Server Components
TypeScript1import { getTranslations } from 'next-intl/server'; 2 3export default async function ProductPage() { 4 const t = await getTranslations('product'); 5 6 return ( 7 <div> 8 <h1>{t('title')}</h1> 9 <p>{t('description')}</p> 10 </div> 11 ); 12}
Client Components
TypeScript1'use client'; 2 3import { useTranslations } from 'next-intl'; 4 5export function AddToCartButton() { 6 const t = useTranslations('product'); 7 8 return ( 9 <button onClick={handleAddToCart}> 10 {t('addToCart')} 11 </button> 12 ); 13}
Variablen und Pluralisierung
JSON1{ 2 "cart": { 3 "items": "{count, plural, =0 {Ihr Warenkorb ist leer} one {# Artikel im Warenkorb} other {# Artikel im Warenkorb}}" 4 } 5}
TypeScriptt('cart.items', { count: 3 }) // "3 Artikel im Warenkorb"
Tipp: Nutzen Sie unseren kostenlosen ICU Message Editor um ICU Pluralisierungs-Syntax visuell zu erstellen und zu testen, bevor Sie sie zu Ihren Übersetzungsdateien hinzufügen.
SEO-Einstellungen
hreflang Tags
TypeScript1export async function generateMetadata({ params: { locale } }) { 2 const t = await getTranslations('meta'); 3 4 return { 5 title: t('title'), 6 alternates: { 7 canonical: `https://example.com/${locale}`, 8 languages: { 9 'en': 'https://example.com/en', 10 'de': 'https://example.com/de', 11 'x-default': 'https://example.com/en' 12 } 13 } 14 }; 15}
Sprachumschalter
TypeScript1'use client'; 2 3import { useLocale } from 'next-intl'; 4import { usePathname, useRouter } from 'next-intl/client'; 5 6export function LanguageSwitcher() { 7 const locale = useLocale(); 8 const pathname = usePathname(); 9 const router = useRouter(); 10 11 const switchLocale = (newLocale: string) => { 12 router.replace(pathname, { locale: newLocale }); 13 }; 14 15 return ( 16 <select value={locale} onChange={(e) => switchLocale(e.target.value)}> 17 <option value="en">English</option> 18 <option value="de">Deutsch</option> 19 <option value="es">Español</option> 20 </select> 21 ); 22}
Wenn JSON-Dateien zum Problem werden
Bei etwa 500 Übersetzungs-Keys wird manuelles JSON-Management schmerzhaft:
- Übersetzer brechen versehentlich die JSON-Syntax
- Keine Möglichkeit zu sehen, was zwischen Sprachen fehlt
- Neue Schlüssel in 12 Dateien kopieren und einfügen
Schnelle Lösung für JSON-Probleme: Unser kostenloses JSON Übersetzungs-Vergleichs-Tool hilft Ihnen, Übersetzungsdateien über Sprachen hinweg zu vergleichen und sofort fehlende Schlüssel zu erkennen.
Hier hilft ein Translation Management System. Ich verwende IntlPull für meine aktuellen Projekte—es ist speziell für Next.js i18n-Workflows gebaut. Der Workflow sieht so aus:
Terminal1# Quell-Strings pushen 2npx @intlpullhq/cli upload 3 4# KI-Übersetzungen holen 5npx @intlpullhq/cli translate --languages de,es,fr 6 7# Alles zurückziehen 8npx @intlpullhq/cli download
Warum IntlPull für Next.js-Projekte:
- Native next-intl Integration - Funktioniert mit Ihrer bestehenden Ordnerstruktur
- KI-gestützte Übersetzungen - Sofortige Übersetzungen mit Kontext-Bewusstsein
- Git-freundlicher Workflow - Übersetzungen direkt in Ihr Repo ziehen
- OTA-Updates - Übersetzungen ohne Neubereitstellung aktualisieren
- Kostenloses Tier - Deckt die meisten Nebenprojekte und Startups ab
Zusammenfassung
Next.js 15s App Router macht i18n wirklich besser. Server Components waren das fehlende Stück.
Wenn Sie gerade anfangen:
- next-intl mit der obigen Ordnerstruktur einrichten
- Routing mit Middleware zum Laufen bringen
- Übersetzungen schrittweise hinzufügen
- Wenn JSON-Dateien zu viel werden, ein TMS wie IntlPull nutzen
IntlPull hat ein kostenloses Tier für die meisten Nebenprojekte. JSON-Dateien funktionieren gut bis sie es nicht mehr tun—dann hilft ein TMS.
