So erstellen Sie mehrsprachige Sitemaps in Next.js (Pages Router) v16

Sitemaps nach Sprache für Skalierbarkeit organisieren

Problem

Sitemaps helfen Suchmaschinen, Seiten auf einer Website zu entdecken und zu indexieren. Für eine mehrsprachige Website mit Hunderten oder Tausenden von Seiten pro Sprache wird eine einzelne Sitemap, die jede URL für jedes Gebietsschema auflistet, schnell unüberschaubar. Große monolithische Sitemaps können die vom Sitemap-Protokoll definierten Grenzwerte von 50.000 URLs oder 50 MB überschreiten und werden dadurch ungültig. Selbst wenn sie innerhalb der Grenzwerte bleiben, ist die Neugenerierung und Validierung einer riesigen Datei bei jeder Inhaltsänderung in einer Sprache ineffizient. Wenn die Website wächst und weitere Sprachen oder Seiten hinzugefügt werden, skaliert dieser Ansatz nicht.

Lösung

Organisieren Sie Sitemaps in einer Hierarchie mithilfe einer Sitemap-Indexdatei. Die Indexdatei listet separate sprachspezifische Sitemaps auf, die jeweils URLs für ein einzelnes Gebietsschema enthalten. Diese Struktur hält einzelne Sitemap-Dateien überschaubar und innerhalb der Protokollgrenzen. Wenn sich Inhalte in einer Sprache ändern, muss nur die Sitemap dieser Sprache neu generiert werden. Der Ansatz skaliert natürlich, wenn neue Sprachen hinzugefügt werden – jede erhält ihre eigene Sitemap, die im Index referenziert wird. Suchmaschinen crawlen zuerst den Index und folgen dann den Links zu einzelnen Sprach-Sitemaps.

Schritte

1. Sitemap-Indexseite erstellen

Erstellen Sie eine Seite im pages-Verzeichnis, um den Sitemap-Index dynamisch mit getServerSideProps zu generieren.

import { GetServerSideProps } from "next";

const SITE_URL = "https://example.com";
const LOCALES = ["en", "es", "fr", "de"];

function generateSitemapIndex(locales: string[]): string {
  const sitemapEntries = locales
    .map((locale) => {
      return `
<sitemap>
  <loc>${SITE_URL}/sitemap-${locale}.xml</loc>
  <lastmod>${new Date().toISOString()}</lastmod>
</sitemap>`;
    })
    .join("");

  return `<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${sitemapEntries}
</sitemapindex>`;
}

export const getServerSideProps: GetServerSideProps = async ({ res }) => {
  const sitemap = generateSitemapIndex(LOCALES);

  res.setHeader("Content-Type", "text/xml");
  res.write(sitemap);
  res.end();

  return {
    props: {},
  };
};

export default function SitemapIndex() {}

Der Index verwendet das <sitemapindex>-Root-Element mit <sitemap>-Einträgen, die jeweils ein <loc>-Child-Element enthalten, das auf eine sprachspezifische Sitemap verweist. Die getServerSideProps-Funktion setzt den Content-Type-Header auf text/xml und schreibt die XML-Antwort direkt.

2. Sprachspezifische Sitemap-Seiten erstellen

Erstellen Sie eine dynamische Route-Seite, um individuelle Sitemaps für jede Sprache zu generieren.

import { GetServerSideProps } from "next";

const SITE_URL = "https://example.com";

interface PageData {
  slug: string;
  lastModified: string;
}

async function getPagesByLocale(locale: string): Promise<PageData[]> {
  return [
    { slug: "about", lastModified: "2024-01-15" },
    { slug: "contact", lastModified: "2024-01-20" },
  ];
}

function generateSitemap(locale: string, pages: PageData[]): string {
  const urlEntries = pages
    .map((page) => {
      return `
<url>
  <loc>${SITE_URL}/${locale}/${page.slug}</loc>
  <lastmod>${page.lastModified}</lastmod>
</url>`;
    })
    .join("");

  return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urlEntries}
</urlset>`;
}

export const getServerSideProps: GetServerSideProps = async ({
  params,
  res,
}) => {
  const locale = params?.locale as string;

  const pages = await getPagesByLocale(locale);
  const sitemap = generateSitemap(locale, pages);

  res.setHeader("Content-Type", "text/xml");
  res.write(sitemap);
  res.end();

  return {
    props: {},
  };
};

export default function LocaleSitemap() {}

Die dynamische Route extrahiert das Gebietsschema aus den URL-Parametern und generiert XML, das nur URLs für diese Sprache enthält. Jede Sitemap bleibt auf den Inhalt eines einzelnen Gebietsschemas fokussiert.

3. Gebietsschemaspezifische Inhalte abrufen

Ersetzen Sie die Platzhalter-Funktion getPagesByLocale durch Ihre tatsächliche Datenquelle.

async function getPagesByLocale(locale: string): Promise<PageData[]> {
  const response = await fetch(
    `https://api.example.com/pages?locale=${locale}`,
  );
  const data = await response.json();

  return data.pages.map((page: any) => ({
    slug: page.slug,
    lastModified: page.updatedAt,
  }));
}

Diese Funktion fragt Ihr CMS, Ihre Datenbank oder API ab, um Seiten für das angegebene Gebietsschema abzurufen. Sie gibt strukturierte Daten zurück, die der Sitemap-Generator in XML-Einträge umwandelt.

4. Statische Seiten zu jeder Sitemap hinzufügen

Fügen Sie statische Routen, die in jeder Sprache existieren, zusammen mit dynamischen Inhalten hinzu.

function generateSitemap(locale: string, pages: PageData[]): string {
  const staticPages = [
    { slug: "", lastModified: new Date().toISOString() },
    { slug: "about", lastModified: new Date().toISOString() },
  ];

  const allPages = [...staticPages, ...pages];

  const urlEntries = allPages
    .map((page) => {
      const path = page.slug ? `/${locale}/${page.slug}` : `/${locale}`;
      return `
<url>
  <loc>${SITE_URL}${path}</loc>
  <lastmod>${page.lastModified}</lastmod>
</url>`;
    })
    .join("");

  return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urlEntries}
</urlset>`;
}

Die Kombination von statischen und dynamischen Seiten stellt sicher, dass jede Sprach-Sitemap vollständig ist. Statische Seiten verwenden den aktuellen Zeitstempel als Datum der letzten Änderung.

5. Index in robots.txt referenzieren

Fügen Sie den Speicherort des Sitemap-Index zu Ihrer robots.txt-Datei hinzu, damit Suchmaschinen ihn entdecken.

User-agent: *
Allow: /

Sitemap: https://example.com/sitemap.xml

Sie müssen nur die Index-Datei auflisten; Suchmaschinen folgen automatisch den Links zu den einzelnen Sprach-Sitemaps. Platzieren Sie diese Datei im public-Verzeichnis.