Übersetzen von Seiten-Metadaten
Festlegen lokalisierter <title>- und <description>-Tags
Problem
Ein Benutzer betrachtet eine Seite auf Spanisch, und alle sichtbaren Inhalte sind korrekt übersetzt. Der Browser-Tab und das Suchmaschinenergebnis-Snippet zeigen jedoch weiterhin den englischen Titel und die englische Beschreibung an. Diese Metadaten-Diskrepanz führt zu einer verwirrenden Benutzererfahrung und schadet der SEO, indem irrelevante Informationen in der Suche präsentiert werden.
Lösung
Verwenden Sie die Next.js generateMetadata-Funktion innerhalb Ihrer Seiten und Layouts. Diese serverseitige Funktion kann die korrekten Übersetzungen basierend auf dem lang-Parameter laden (unter Verwendung derselben Dictionary-Ladelogik wie Ihre Komponenten) und ein dynamisches metadata-Objekt mit dem lokalisierten Titel und der lokalisierten Beschreibung zurückgeben.
Schritte
1. Erstellen Sie eine Funktion zum Laden von Dictionaries
Sie benötigen eine Möglichkeit, Ihre flachen Übersetzungsdateien auf dem Server zu laden. Erstellen Sie dafür eine Hilfsfunktion.
// app/get-dictionary.ts
import 'server-only';
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),
};
export const getDictionary = async (lang: string) => {
const load = dictionaries[lang];
if (load) {
return load();
}
return dictionaries.en();
};
2. Definieren Sie Metadaten auf einer Seite
In Ihrer Seitendatei (z. B. app/[lang]/about/page.tsx) exportieren Sie eine async-Funktion namens generateMetadata. Next.js ruft diese automatisch beim Rendern der Seite auf.
// app/[lang]/about/page.tsx
import { getDictionary } from '@/app/get-dictionary';
import type { Metadata } from 'next';
type Props = {
params: { lang: string };
};
// This function generates metadata
export async function generateMetadata({ params }: Props): Promise<Metadata> {
// Load the dictionary for this page
const dict = await getDictionary(params.lang);
return {
title: dict['about.title'], // e.g., "About Us" or "Sobre Nosotros"
description: dict['about.description'],
};
}
// The rest of your page component
export default function AboutPage() {
return (
<div>
{/* Page content */}
<h1>...</h1>
</div>
);
}
3. Legen Sie eine Titelvorlage im Root-Layout fest
Um zu vermeiden, dass Sie Ihren Seitennamen in jedem Titel wiederholen, können Sie eine Vorlage in Ihrem Root-Layout festlegen.
// app/[lang]/layout.tsx
import { getDictionary } from '@/app/get-dictionary';
import type { Metadata } from 'next';
type Props = {
params: { lang: string };
children: React.ReactNode;
};
// You can generate metadata in layouts too
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const dict = await getDictionary(params.lang);
return {
// This provides a base title and a template
title: {
default: dict['site.name'], // e.g., "My Awesome Site"
template: `%s | ${dict['site.name']}`, // e.g., "About Us | My Awesome Site"
},
description: dict['site.description'],
};
}
export default async function RootLayout({ children, params }: Props) {
// ... rest of your layout (loading providers, etc.)
return (
<html lang={params.lang}>
<body>{children}</body>
</html>
);
}