aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webentwicklung

Next.js SEO: Titel, OG und Canonical mit der Metadata-API

Wenn von Next.js SEO die Rede ist, denkt man zuerst daran, den <head> der Seite korrekt zu füllen: einen aussagekräftigen Titel, eine beschreibende Description, Open-Graph-Tags fürs Teilen in sozialen Netzwerken und einen Canonical-Link, der doppelte Inhalte verhindert. Die mit dem App Router gelieferte Metadata-API erlaubt all das, ohne den <head> von Hand zu schreiben — typsicher und serverseitig aufgelöst. In dieser Anleitung gehe ich einen praktischen Aufbau durch, vom statischen metadata-Objekt bis zur dynamischen Funktion generateMetadata.

Was ist die Metadata-API?

Im App Router (Next.js 13.2 und später) kann jede layout.tsx- und page.tsx-Datei Metadaten auf eine von zwei Arten exportieren: ein metadata-Objekt für konstante Werte oder eine asynchrone Funktion generateMetadata für Werte, die von der Anfrage oder von Daten abhängen. Next.js liest diese und erzeugt den <head> der Seite für dich. Eine wichtige Regel: Diese Exporte funktionieren nur in Server-Component-Dateien; aus einer mit "use client" markierten Datei kannst du keine Metadaten exportieren.

Titel und Description mit statischen Metadaten

Die einfachste Form ist der Export eines konstanten Objekts. Meist legst du ein seitenweites in der Root-app/layout.tsx an und fügst dann seitenspezifische pro Route hinzu.

// app/layout.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: {
    default: "aslain.dev — Web- & Spieleentwicklung",
    template: "%s | aslain.dev",
  },
  description: "Anleitungen zu Web, Gameservern und Discord-Bot-Entwicklung.",
};

Das Feld title.template ist ein mächtiges Werkzeug: Unterseiten liefern nur ihren eigenen Titel, und Next.js setzt ihn in %s ein und hängt den Sitenamen an. Setzt eine Seite etwa title: "Kontakt", lautet die Ausgabe Kontakt | aslain.dev. Du musst deinen Markennamen nicht mehr in jedem Titel von Hand wiederholen.

Dynamisches Next.js SEO mit generateMetadata

Bei Routen, deren Inhalt aus einer Datenbank stammt — Blogbeiträge, Produktseiten — müssen Titel und Description ebenfalls dynamisch sein. Hier kommt generateMetadata ins Spiel. Es erhält dasselbe params-Argument wie die Seite selbst, lädt Daten und gibt Metadaten zurück.

// app/blog/[slug]/page.tsx
import type { Metadata } from "next";

export async function generateMetadata(
  { params }: { params: Promise<{ slug: string }> }
): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);

  return {
    title: post.title,
    description: post.excerpt,
  };
}

In Next.js 15 wurde params zu einem Promise, deshalb musst du es mit await auflösen. Ein wichtiger Performance-Hinweis: fetch-Aufrufe innerhalb von generateMetadata werden durch die Request-Memoization von Next.js dedupliziert, wenn sie in derselben Seitenkomponente wiederholt werden; du musst dieselben Daten also nicht zweimal abrufen befürchten.

Open-Graph- und Twitter-Karten

Wie dein Link aussieht, wenn er auf WhatsApp, X oder LinkedIn geteilt wird, steuern die Open-Graph-Tags. Die Metadata-API stellt sie sauber unter den Schlüsseln openGraph und twitter bereit.

export const metadata: Metadata = {
  openGraph: {
    title: "Next.js-SEO-Leitfaden",
    description: "Titel, OG und Canonical mit der Metadata-API.",
    url: "https://aslain.dev/blog/nextjs-seo",
    siteName: "aslain.dev",
    images: [{ url: "/og/nextjs-seo.png", width: 1200, height: 630 }],
    locale: "de_DE",
    type: "article",
  },
  twitter: {
    card: "summary_large_image",
    title: "Next.js-SEO-Leitfaden",
    images: ["/og/nextjs-seo.png"],
  },
};
  • Bildgröße: 1200×630 Pixel ist das Standardverhältnis, das soziale Plattformen erwarten.
  • type: "article": der richtige OG-Typ für Blogbeiträge; nutze "website" für die Startseite.
  • Gibst du die Twitter-Karte nicht separat an, werden die meisten Felder von Open Graph geerbt; dennoch ist es gute Praxis, den card-Typ explizit zu setzen.

Canonical und Sprachalternativen

Ist derselbe Inhalt über mehrere URLs erreichbar (abschließender Schrägstrich, Tracking-Parameter), ist ein Canonical-Tag unverzichtbar, um Suchmaschinen die maßgebliche Adresse mitzuteilen. Die Metadata-API liefert ihn unter alternates.

export const metadata: Metadata = {
  metadataBase: new URL("https://aslain.dev"),
  alternates: {
    canonical: "/blog/nextjs-seo",
    languages: {
      "de-DE": "/de/blog/nextjs-seo",
      "en-US": "/en/blog/nextjs-seo",
    },
  },
};

Definiere immer metadataBase: Relative Pfade (wie /blog/... oder /og/...) werden relativ zu dieser Basis in absolute URLs aufgelöst. Lässt du es weg, warnt Next.js während der Entwicklung, und OG-Bilder erscheinen auf manchen Plattformen möglicherweise nicht, weil sie keine absolute URL haben. Die unter languages aufgeführten Alternativen werden zu hreflang-Tags und stärken mehrsprachiges SEO.

Häufige Fehler

  • Export aus einer Client-Komponente: Metadaten aus einer "use client"-Datei zu exportieren, bleibt stillschweigend wirkungslos; halte Metadaten in einer Server-Komponente.
  • metadataBase vergessen: OG-Bilder und Canonical brechen, weil sie relativ bleiben.
  • Titel doppelt definieren: title und openGraph.title können sich unterscheiden; hältst du sie nicht konsistent, wirkt das Teilen verwirrend.
  • Einen manuellen <head> beimischen: Schreibe im App Router kein <head>-Element von Hand — die Metadata-API soll die einzige Quelle der Wahrheit sein.

Häufige Fragen

Soll ich das metadata-Objekt oder generateMetadata verwenden?

Sind die Werte konstant (statische Seiten, das Root-Layout), ist das metadata-Objekt einfacher und schneller. Stammen Titel oder Description aus Daten, Params oder der Anfrage, nutze generateMetadata. Exportiere nicht beides aus derselben Datei; Next.js lässt das nicht zu.

Erzeugt die Metadata-API auch Sitemap- und Robots-Dateien?

Ja. Die Dateien app/sitemap.ts und app/robots.ts fallen unter die dateibasierten Metadaten-Konventionen, und Next.js wandelt sie automatisch in die Endpunkte /sitemap.xml und /robots.txt um. Ebenso werden app/icon.png und app/opengraph-image.tsx erkannt.

Verlangsamt generateMetadata das Laden der Seiten?

Meist nicht. Seine Datenaufrufe nutzen denselben Cache wie die Seitenkomponente (Request-Memoization), sodass derselbe fetch keine zwei Netzwerkanfragen auslöst. Vermeide dennoch unnötig schwere Abfragen und bevorzuge wo möglich cachefähige Datenquellen.

Möchtest du die Next.js-SEO-Grundlage deiner Website von Grund auf aufbauen oder deine bestehenden Metadaten prüfen lassen? Lass uns die App-Router-, Open-Graph- und Canonical-Struktur rund um dein Projekt bauen — nimm Kontakt mit mir auf.

Bu kategorideki tüm yazılar →

Devamı için