Übersetzungen laden
Verwendung eines Providers zur Verwaltung von Nachrichten
Problem
Das Hardcoding von Text, wie 'Hello World', direkt in die Komponenten einer Anwendung koppelt den Inhalt mit dem Code. Um eine andere Sprache anzuzeigen, müssen Entwickler die Komponente duplizieren oder if/else-Logik hinzufügen, was die Übersetzung nicht skalierbar macht und für jedes neue Textstück eine vollständige Codeänderung erfordert.
Lösung
Verwenden Sie den IntlProvider von react-intl, um Übersetzungen bereitzustellen. Laden Sie Übersetzungsnachrichten auf dem Server im Root-Layout, übergeben Sie sie an eine clientseitige Provider-Komponente und nutzen Sie sie dann in anderen Client-Komponenten mit dem useIntl-Hook.
Schritte
1. Installieren Sie react-intl
Fügen Sie zunächst react-intl als Abhängigkeit zu Ihrem Projekt hinzu.
npm install react-intl
2. Erstellen Sie flache Übersetzungsdateien
Erstellen Sie einen dictionaries-Ordner. Fügen Sie darin eine JSON-Datei für jede Sprache hinzu. react-intl funktioniert am besten mit einer flachen Schlüssel-Wert-Struktur.
// dictionaries/en.json
{
"home.title": "Home Page",
"home.welcome": "Hello, welcome to our site!",
"about.title": "About Us"
}
// dictionaries/es.json
{
"home.title": "Página de Inicio",
"home.welcome": "¡Hola, bienvenido a nuestro sitio!",
"about.title": "Sobre Nosotros"
}
3. Erstellen Sie eine Funktion zum Laden von Wörterbüchern
Erstellen Sie eine Hilfsfunktion, um die richtige Wörterbuchdatei auf dem Server basierend auf dem lang-Parameter zu laden.
// app/get-dictionary.ts
import 'server-only';
// Define the type for our flat message object
type Messages = Record<string, string>;
const dictionaries: { [key: string]: () => Promise<Messages> } = {
en: () => import('@/dictionaries/en.json').then((module) => module.default),
es: () => import('@/dictionaries/es.json').then((module) => module.default),
// fr: () => import('@/dictionaries/fr.json').then((module) => module.default),
};
export const getDictionary = async (lang: string) => {
const load = dictionaries[lang];
if (load) {
return load();
}
// Fallback to English
return dictionaries.en();
};
4. Erstellen eines clientseitigen Providers
IntlProvider ist eine Client-Komponente, die den Context von React verwendet. Wir müssen einen Wrapper dafür erstellen, der Nachrichten vom Server laden kann.
// app/components/IntlClientProvider.tsx
'use client';
import { IntlProvider } from 'react-intl';
type Props = {
children: React.ReactNode;
locale: string;
messages: Record<string, string>; // Flat messages object
};
export default function IntlClientProvider({
children,
locale,
messages,
}: Props) {
return (
<IntlProvider messages={messages} locale={locale} defaultLocale="en">
{children}
</IntlProvider>
);
}
5. Aktualisieren des Root-Layouts
Modifizieren Sie Ihr app/[lang]/layout.tsx, um eine async-Komponente zu erstellen. Diese wird die Nachrichten laden und an den IntlClientProvider übergeben.
// app/[lang]/layout.tsx
import { getDictionary } from '@/app/get-dictionary';
import IntlClientProvider from '@/app/components/IntlClientProvider';
export async function generateStaticParams() {
return [{ lang: 'en' }, { lang: 'es' }];
}
export default async function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: { lang: string };
}) {
// Load messages on the server
const messages = await getDictionary(params.lang);
return (
<html lang={params.lang}>
<body>
{/* Pass messages to the client provider */}
<IntlClientProvider locale={params.lang} messages={messages}>
{children}
</IntlClientProvider>
</body>
</html>
);
}
6. Verwendung von Übersetzungen in einer Client-Komponente
Sie können jetzt den useIntl-Hook in jeder Client-Komponente verwenden. Server-Komponenten können diesen Hook nicht nutzen.
Erstellen Sie eine neue Client-Komponente, um den übersetzten Text anzuzeigen:
// app/components/HomePageContent.tsx
'use client';
import { useIntl } from 'react-intl';
export default function HomePageContent() {
const intl = useIntl();
return (
<div>
<h1>{intl.formatMessage({ id: 'home.title' })}</h1>
<p>{intl.formatMessage({ id: 'home.welcome' })}</p>
</div>
);
}
7. Fügen Sie die Komponente zu Ihrer Seite hinzu
Fügen Sie schließlich Ihre neue Client-Komponente zu Ihrer Seite hinzu.
// app/[lang]/page.tsx
import HomePageContent from '@/app/components/HomePageContent';
export default function Home() {
// Diese Seite ist eine Server-Komponente
return (
<div>
{/* Sie rendert die Client-Komponente */}
<HomePageContent />
</div>
);
}