Du hast eine Next.js-Seite gebaut und die Share-Vorschau zeigt eine leere Karte. Der App Router bringt eine Metadata API, die manuelle <head>-Tags ersetzt. Richtig eingesetzt liefern Crawler beim ersten Request og:title, og:image und den Rest im Server-HTML.
Kurzantwort
Im Next.js App Router definierst du Open-Graph-Tags über den metadata-Export für statische Seiten oder generateMetadata für dynamische Routen. Setze openGraph.title, openGraph.description, openGraph.images und openGraph.url im Metadata-Objekt. Next.js rendert daraus <meta property="og:*">-Tags in der initialen HTML-Antwort. Nutze immer absolute HTTPS-URLs für Bilder. Nach dem Deploy die Live-URL mit OpenGraph Check scannen, bevor du teilst.
Warum Next.js-Vorschauen brechen
Social Crawler laden HTML einmal und lesen den <head>. Sie führen kein React aus und warten nicht auf Client-Hydration. Typische Next.js-Fehler:
- Meta-Tags nur in einer Client-Komponente
- Relative
og:image-Pfade wie/og.jpgohne Base-URL generateMetadataholt Draft-Inhalte, die von Production abweichen- Bild-Routen hinter Auth oder mit Redirects
- Fehlende Tags in verschachtelten Layouts durch falsche Overrides
Die Metadata API löst das, solange alle OG-Werte serverseitig bleiben.
Statischer metadata-Export
Für Seiten mit festem Inhalt exportierst du ein metadata-Objekt aus page.tsx oder layout.tsx:
import type { Metadata } from "next";export const metadata: Metadata = { title: "Produktlaunch 2026", description: "Alles Wichtige zu unserem neuen Release.", openGraph: { title: "Produktlaunch 2026", description: "Alles Wichtige zu unserem neuen Release.", url: "https://example.com/launch", siteName: "Example Co", images: [ { url: "https://example.com/og/launch.jpg", width: 1200, height: 630, alt: "Produktlaunch Hero-Bild", }, ], locale: "de_DE", type: "website", }, twitter: { card: "summary_large_image", title: "Produktlaunch 2026", description: "Alles Wichtige zu unserem neuen Release.", images: ["https://example.com/og/launch.jpg"], },};Next.js wandelt das in Meta-Tags im Document Head um. Child-Layouts mergen mit Parent-Layouts, sofern du metadataBase im Root setzt.
metadataBase einmal im Root setzen
Relative Bildpfade funktionieren nur mit metadataBase im Root-Layout:
export const metadata: Metadata = { metadataBase: new URL("https://example.com"), openGraph: { images: ["/og/default.jpg"], },};Ohne metadataBase kann Next.js kaputte relative URLs ausgeben, die Crawler ablehnen. Setze es in app/layout.tsx.
Dynamische Routen mit generateMetadata
Blogposts, Produktseiten und CMS-Inhalte brauchen async Metadata:
import type { Metadata } from "next";type Props = { params: Promise<{ slug: string }> };export async function generateMetadata({ params }: Props): Promise<Metadata> { const { slug } = await params; const post = await getPost(slug); return { title: post.title, description: post.excerpt, openGraph: { title: post.title, description: post.excerpt, url: `https://example.com/blog/${slug}`, type: "article", publishedTime: post.publishedAt, authors: [post.author.name], images: [ { url: post.ogImageUrl, width: 1200, height: 630, }, ], }, };}Daten in generateMetadata fetchen, nicht in einem Client-Hook. Die Funktion läuft serverseitig beim HTML-Request.
og:image-Strategien in Next.js
Statische Dateien in /public
Lege og.jpg in public/ ab:
openGraph: { images: ["https://example.com/og.jpg"],}Einfach und zuverlässig. Gut für Marketing-Seiten mit einem gemeinsamen Bild.
Dynamische OG-Bilder mit ImageResponse
Next.js unterstützt dynamische OG-Bilder über opengraph-image.tsx:
import { ImageResponse } from "next/og";export const runtime = "edge";export const alt = "Blogpost-Titel";export const size = { width: 1200, height: 630 };export default async function Image({ params }: { params: { slug: string } }) { const post = await getPost(params.slug); return new ImageResponse( ( <div style={{ fontSize: 60, background: "#000", color: "#fff", width: "100%", height: "100%" }}> {post.title} </div> ), { ...size } );}Next.js verdrahtet die Route automatisch als og:image. Teste die generierte Bild-URL nach dem Deploy direkt im Browser.
Remote-Bilder aus dem CMS
Kommen Bilder von Contentful, Sanity oder einem CDN, übergib die volle HTTPS-URL. Prüfe, ob das CDN Crawler-Zugriff ohne Cookies erlaubt. Siehe Fehlendes OG-Bild beheben bei Problemen.
Layout-Vererbung und Overrides
Metadata merged vom Root-Layout zur Seite. Eine Child-Seite ersetzt Parent-Felder, die sie definiert. Setzt ein Child openGraph: { title: "Über uns" } ohne Images, können Parent-Bilder je nach Merge-Verhalten fehlen.
Sicheres Muster: Defaults im Root-Layout, pro Seite nur Änderungen:
// app/layout.tsx - Defaultsexport const metadata: Metadata = { metadataBase: new URL("https://example.com"), openGraph: { siteName: "Example Co", images: ["/og/default.jpg"], },};// app/about/page.tsx - seiten-spezifischexport const metadata: Metadata = { title: "Über uns", openGraph: { title: "Über uns", description: "Unsere Geschichte und das Team.", url: "https://example.com/about", },};Twitter-Card-Tags neben Open Graph
Next.js mappt twitter in Metadata auf twitter:*-Tags. X fällt auf Open Graph zurück, explizite Tags geben mehr Kontrolle. Vergleich: Open Graph vs. Twitter Card.
Häufige Fehler in Next.js-Projekten
Nur clientseitige Metadata
Setze OG-Tags nie mit next/head im App Router oder in "use client"-Komponenten. Crawler sehen sie nicht.
Testen auf localhost
Social Crawler erreichen localhost nicht. Zuerst auf öffentliche HTTPS-URL deployen. Siehe Open-Graph-Tags testen.
Falsche Bildmaße
1200 × 630 px als sicherer Default. Plattform-Details: Open-Graph-Bildgröße.
og:url vergessen
Setze openGraph.url auf die kanonische URL, die du teilst. Abweichung verwirrt Crawler und Analytics.
Stale Cache nach Deploy
Plattformen cachen Vorschauen. Nach Tag-Änderungen Debugger erneut scrapen. Siehe Link-Vorschau-Cache erklärt.
Schritt-für-Schritt-Verifizierung
- Seite auf Production-HTTPS deployen
- Seitenquelltext anzeigen und nach
og:titlesuchen og:image-URL in neuem Tab öffnen (200 OK erwarten)- URL in OpenGraph Check einfügen
- Vorschauen auf Facebook, LinkedIn und WhatsApp prüfen
- Facebook Sharing Debugger bei Meta-Posts nutzen
FAQ
Funktioniert die Metadata API mit dem Pages Router?
Der Pages Router nutzt next/head oder _document.tsx. Die Metadata API ist App-Router-only. Migration zu app/ lohnt sich für die sauberere API.
Geht generateMetadata mit Static Export?
output: "export" unterstützt statische Metadata-Exports. Dynamisches generateMetadata mit Request-Time-Fetch braucht einen Server. Static Export backt Metadata beim Build ein.
Wo erscheinen og-Tags im HTML?
Im <head> des servergerenderten HTML. Prüfen mit Seitenquelltext, nicht im React-DevTools-Elements-Panel.
Wie setze ich og:image nur für eine Route?
Route-Level-Metadata aus der page.tsx exportieren oder opengraph-image.tsx im Route-Ordner anlegen.
Setzt Next.js og:type automatisch?
Default ist website. Für Blogposts openGraph.type: "article" mit publishedTime und authors setzen.
Warum zeigt mein dynamisches OG-Bild den falschen Titel?
Prüfe, ob generateMetadata und opengraph-image.tsx denselben Slug und dieselbe Datenquelle nutzen. Stale ISR-Cache kann Mismatch verursachen. Nach CMS-Updates revalidieren.
Soll ich title in openGraph und metadata.title duplizieren?
Ja. metadata.title setzt den Dokumenttitel und kann ein Template-Suffix haben. openGraph.title steuert die Share-Karten-Überschrift. Die können unterschiedlich sein.
Fazit
Der Next.js App Router macht Open-Graph-Tags einfach, wenn du die Metadata API serverseitig nutzt. metadataBase setzen, metadata oder generateMetadata mit absoluten Bild-URLs exportieren, deployen und mit OpenGraph Check verifizieren. Keine clientseitige Head-Injection - dann stimmen deine Link-Vorschauen.