Übersetzungen laden
Verwendung eines Providers zur Verwaltung von Nachrichten
Problem
Das direkte Einbetten von Text wie „Hello World" 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 jeden neuen Text 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 diese an eine clientseitige Provider-Komponente und nutzen Sie sie dann in anderen Client-Komponenten über den useIntl-Hook.
Schritte
1. react-intl installieren
Fügen Sie zunächst react-intl als Abhängigkeit zu Ihrem Projekt hinzu.
npm install react-intl
2. Flache Übersetzungsdateien erstellen
Erstellen Sie einen dictionaries-Ordner. Fügen Sie darin für jede Sprache eine JSON-Datei hinzu. react-intl funktioniert am besten mit einer flachen Key-Value-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. Funktion zum Laden von Dictionaries erstellen
Erstellen Sie eine Hilfsfunktion, um die korrekte Dictionary-Datei 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. Clientseitigen Provider erstellen
IntlProvider ist eine Client-Komponente, die React Context verwendet. Wir müssen einen Wrapper dafür erstellen, der vom Server geladene Nachrichten akzeptieren 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. Root-Layout aktualisieren
Ändern Sie Ihr app/[lang]/layout.tsx in eine async-Komponente. Diese lädt die Nachrichten und übergibt sie an den IntlClientProvider.
// 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. Übersetzungen in einer Client-Komponente verwenden
Sie können jetzt den useIntl Hook in jeder Client-Komponente verwenden. Server-Komponenten können diesen Hook nicht verwenden.
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. Komponente zu Ihrer Seite hinzufügen
Fügen Sie abschließend Ihre neue Client-Komponente zu Ihrer Seite hinzu.
// app/[lang]/page.tsx
import HomePageContent from '@/app/components/HomePageContent';
export default function Home() {
// This page is a Server Component
return (
<div>
{/* It renders the Client Component */}
<HomePageContent />
</div>
);
}