Verknüpfung alternativer Sprachversionen (hreflang)
Suchmaschinen über Ihre lokalisierten Seiten informieren
Problem
Eine Anwendung hat identische Inhalte unter /en/page und /fr/page verfügbar. Suchmaschinen betrachten diese als zwei separate, konkurrierende Seiten. Ohne einen Mechanismus zur Verknüpfung werden die Suchrankings aufgeteilt, und Benutzern in Frankreich wird möglicherweise die englische Seite in den Suchergebnissen angezeigt, anstatt der französischen.
Lösung
Verwenden Sie die alternates-Eigenschaft innerhalb der Next.js-Funktion generateMetadata. Durch die Bereitstellung einer Liste aller verfügbaren Sprachen für eine bestimmte Seite generiert Next.js automatisch <link rel="alternate" hreflang="..." />-Tags im <head>-Bereich des Dokuments, wodurch die Beziehung zwischen diesen Seiten für Suchmaschinen signalisiert wird.
Schritte
1. Definieren Sie die Basis-URL Ihrer Website
hreflang-Tags erfordern absolute, nicht relative URLs. Speichern Sie die kanonische Basis-URL Ihrer Website in einer Konfigurationsdatei.
// i18n-config.ts
export const locales = ['en', 'es', 'fr'];
export const defaultLocale = 'en';
export const siteBaseUrl = 'https://www.example.com'; // Ihre Produktions-URL
2. Fügen Sie alternates zu generateMetadata hinzu
Exportieren Sie in Ihrer app/[lang]/layout.tsx (um sie auf alle Seiten anzuwenden) oder in einer spezifischen Seitendatei eine generateMetadata-Funktion.
// app/[lang]/layout.tsx
import { locales, siteBaseUrl } from '@/i18n-config';
import type { Metadata } from 'next';
type Props = {
params: { lang: string };
children: React.ReactNode;
};
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { lang } = params;
// Create language alternates
const alternatesMap = locales.reduce((acc, locale) => {
acc[locale] = `${siteBaseUrl}/${locale}`;
return acc;
}, {} as Record<string, string>);
return {
alternates: {
canonical: `${siteBaseUrl}/${lang}`,
languages: {
...alternatesMap,
'x-default': `${siteBaseUrl}/${defaultLocale}`,
},
},
};
}
// Rest of your layout component
export default function RootLayout({ children, params }: Props) {
return (
<html lang={params.lang}>
<body>{children}</body>
</html>
);
}
Dieser Code generiert ein languages-Objekt, das jede Locale ihrer absoluten Basis-URL zuordnet (z.B. en: 'https://www.example.com/en'). Er setzt auch eine canonical-URL für die aktuelle Seite und eine x-default-URL, die Suchmaschinen mitteilt, welche Version Benutzern mit nicht spezifizierten Sprachen angezeigt werden soll.
3. alternates für verschachtelte Seiten verwalten
Für verschachtelte Seiten wie /about müssen Sie sicherstellen, dass die Metadaten-Funktion den vollständigen Pfad enthält.
// app/[lang]/about/page.tsx
import { locales, siteBaseUrl, defaultLocale } from '@/i18n-config';
import type { Metadata } from 'next';
type Props = {
params: { lang: string };
};
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { lang } = params;
const path = '/about'; // Der Pfad für diese Seite
// Sprachalternativen erstellen
const alternatesMap = locales.reduce((acc, locale) => {
acc[locale] = `${siteBaseUrl}/${locale}${path}`;
return acc;
}, {} as Record<string, string>);
return {
title: 'About Us', // Fügen Sie Ihren übersetzten Titel hinzu
alternates: {
canonical: `${siteBaseUrl}/${lang}${path}`,
languages: {
...alternatesMap,
'x-default': `${siteBaseUrl}/${defaultLocale}${path}`,
},
},
};
}
export default function AboutPage() {
return <div>About page content</div>;
}