Menu

Metadaten

Next.js stellt eine Metadata API bereit, mit der Sie Anwendungsmetadaten (z.B. meta- und link-Tags innerhalb des HTML-head-Elements) für verbesserte SEO und Web-Sharability definieren können.

Es gibt zwei Möglichkeiten, Metadaten zu Ihrer Anwendung hinzuzufügen:

  • Konfigurationsbasierte Metadaten: Exportieren Sie ein statisches metadata-Objekt oder eine dynamische generateMetadata-Funktion in einer layout.js- oder page.js-Datei.
  • Dateibasierte Metadaten: Fügen Sie statische oder dynamisch generierte spezielle Dateien zu Routensegmenten hinzu.

Mit beiden Optionen generiert Next.js automatisch die relevanten <head>-Elemente für Ihre Seiten. Sie können auch dynamische OG-Bilder mit dem ImageResponse-Konstruktor erstellen.

Statische Metadaten

Um statische Metadaten zu definieren, exportieren Sie ein Metadata-Objekt aus einer layout.js- oder statischen page.js-Datei.

layout.tsx
TypeScript
import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: '...',
  description: '...',
}
 
export default function Page() {}

Alle verfügbaren Optionen finden Sie in der API-Referenz.

Dynamische Metadaten

Sie können die generateMetadata-Funktion verwenden, um Metadaten zu fetchen, die dynamische Werte erfordern.

app/products/[id]/page.tsx
TypeScript
import type { Metadata, ResolvingMetadata } from 'next'
 
type Props = {
  params: Promise<{ id: string }>
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}
 
export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  // Routenparameter lesen
  const id = (await params).id
 
  // Daten fetchen
  const product = await fetch(`https://.../${id}`).then((res) => res.json())
 
  // Optional auf übergeordnete Metadaten zugreifen und diese erweitern
  const previousImages = (await parent).openGraph?.images || []
 
  return {
    title: product.title,
    openGraph: {
      images: ['/some-specific-page-image.jpg', ...previousImages],
    },
  }
}
 
export default function Page({ params, searchParams }: Props) {}

Alle verfügbaren Parameter finden Sie in der API-Referenz.

Hinweis:

  • Sowohl statische als auch dynamische Metadaten über generateMetadata werden nur in Server-Komponenten unterstützt.
  • fetch-Anfragen werden automatisch memoized für dieselben Daten über generateMetadata, generateStaticParams, Layouts, Seiten und Server-Komponenten. React cache kann verwendet werden, wenn fetch nicht verfügbar ist.
  • Next.js wartet, bis das Datenfetchen in generateMetadata abgeschlossen ist, bevor die Benutzeroberfläche an den Client gestreamt wird. Dies garantiert, dass der erste Teil einer gestreamten Antwort <head>-Tags enthält.

Dateibasierte Metadaten

Diese speziellen Dateien sind für Metadaten verfügbar:

Sie können diese für statische Metadaten verwenden oder diese Dateien programmgesteuert mit Code generieren.

Weitere Informationen und Beispiele finden Sie in der Metadaten-Dateien API-Referenz und Dynamische Bildgenerierung.

Verhalten

Dateibasierte Metadaten haben die höhere Priorität und überschreiben konfigurationsbasierte Metadaten.

Standardfelder

Es gibt zwei standardmäßige meta-Tags, die auch dann hinzugefügt werden, wenn eine Route keine Metadaten definiert:

  • Der meta charset-Tag legt die Zeichenkodierung für die Website fest.
  • Der meta viewport-Tag legt die Viewport-Breite und -Skalierung für die Website fest, um sie an verschiedene Geräte anzupassen.
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

Hinweis: Sie können den Standard-viewport meta-Tag überschreiben.

Reihenfolge

Metadaten werden in Reihenfolge ausgewertet, beginnend vom Root-Segment bis zum Segment, das der endgültigen page.js am nächsten ist. Zum Beispiel:

  1. app/layout.tsx (Root-Layout)
  2. app/blog/layout.tsx (Verschachteltes Blog-Layout)
  3. app/blog/[slug]/page.tsx (Blog-Seite)

Zusammenführen

Gemäß der Auswertungsreihenfolge werden Metadaten-Objekte, die aus mehreren Segmenten in derselben Route exportiert werden, flach zusammengeführt, um die endgültigen Metadaten einer Route zu bilden. Doppelte Schlüssel werden ersetzt basierend auf ihrer Reihenfolge.

Das bedeutet, Metadaten mit verschachtelten Feldern wie openGraph und robots, die in einem früheren Segment definiert sind, werden überschrieben durch das letzte Segment, das sie definiert.

Felder überschreiben

app/layout.js
export const metadata = {
  title: 'Acme',
  openGraph: {
    title: 'Acme',
    description: 'Acme ist eine...',
  },
}
app/blog/page.js
export const metadata = {
  title: 'Blog',
  openGraph: {
    title: 'Blog',
  },
}
 
// Ausgabe:
// <title>Blog</title>
// <meta property="og:title" content="Blog" />

Im obigen Beispiel:

  • title von app/layout.js wird durch title in app/blog/page.js ersetzt.
  • Alle openGraph-Felder von app/layout.js werden in app/blog/page.js ersetzt, da app/blog/page.js OpenGraph-Metadaten setzt. Beachten Sie das Fehlen von openGraph.description.

Wenn Sie einige verschachtelte Felder zwischen Segmenten teilen und andere überschreiben möchten, können Sie sie in eine separate Variable auslagern:

app/shared-metadata.js
export const openGraphImage = { images: ['http://...'] }
app/page.js
import { openGraphImage } from './shared-metadata'
 
export const metadata = {
  openGraph: {
    ...openGraphImage,
    title: 'Home',
  },
}
app/about/page.js
import { openGraphImage } from '../shared-metadata'
 
export const metadata = {
  openGraph: {
    ...openGraphImage,
    title: 'About',
  },
}

Im obigen Beispiel wird das OG-Bild zwischen app/layout.js und app/about/page.js geteilt, während die Titel unterschiedlich sind.

Felder erben

app/layout.js
export const metadata = {
  title: 'Acme',
  openGraph: {
    title: 'Acme',
    description: 'Acme ist eine...',
  },
}
app/about/page.js
export const metadata = {
  title: 'About',
}
 
// Ausgabe:
// <title>About</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acme ist eine..." />

Notizen

  • title aus app/layout.js wird durch title in app/about/page.js ersetzt.
  • Alle openGraph-Felder aus app/layout.js werden in app/about/page.js geerbt, da app/about/page.js keine openGraph-Metadaten festlegt.

Dynamische Bilderstellung

Der ImageResponse-Konstruktor ermöglicht es Ihnen, dynamische Bilder mit JSX und CSS zu generieren. Dies ist nützlich für die Erstellung von Social-Media-Bildern wie Open Graph-Bildern, Twitter-Karten und mehr.

Um es zu verwenden, können Sie ImageResponse aus next/og importieren:

app/about/route.js
import { ImageResponse } from 'next/og'
 
export async function GET() {
  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          textAlign: 'center',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        Hallo Welt!
      </div>
    ),
    {
      width: 1200,
      height: 600,
    }
  )
}

ImageResponse integriert sich gut mit anderen Next.js-APIs, einschließlich Route Handlers und dateibasierter Metadaten. Sie können beispielsweise ImageResponse in einer opengraph-image.tsx-Datei verwenden, um Open Graph-Bilder zur Bauzeit oder dynamisch zum Zeitpunkt der Anfrage zu generieren.

ImageResponse unterstützt gängige CSS-Eigenschaften, einschließlich Flexbox und absoluter Positionierung, benutzerdefinierter Schriftarten, Textumbruch, Zentrierung und verschachtelter Bilder. Sehen Sie sich die vollständige Liste der unterstützten CSS-Eigenschaften an.

Hinweis:

  • Beispiele sind im Vercel OG Playground verfügbar.
  • ImageResponse verwendet @vercel/og, Satori und Resvg, um HTML und CSS in PNG zu konvertieren.
  • Nur die Edge Runtime wird unterstützt. Die Standard-Node.js-Laufzeit funktioniert nicht.
  • Nur Flexbox und eine Teilmenge von CSS-Eigenschaften werden unterstützt. Fortgeschrittene Layouts (z. B. display: grid) funktionieren nicht.
  • Maximale Paketgröße von 500KB. Die Paketgröße umfasst Ihr JSX, CSS, Schriftarten, Bilder und alle anderen Assets. Wenn Sie das Limit überschreiten, sollten Sie die Größe der Assets reduzieren oder sie zur Laufzeit abrufen.
  • Nur ttf-, otf- und woff-Schriftformate werden unterstützt. Um die Schriftart-Parsing-Geschwindigkeit zu maximieren, sind ttf oder otf woff vorzuziehen.

JSON-LD

JSON-LD ist ein Format für strukturierte Daten, das von Suchmaschinen verwendet werden kann, um Ihre Inhalte zu verstehen. Sie können es beispielsweise verwenden, um eine Person, ein Ereignis, eine Organisation, einen Film, ein Buch, ein Rezept und viele andere Arten von Entitäten zu beschreiben.

Unsere aktuelle Empfehlung für JSON-LD ist, strukturierte Daten als <script>-Tag in Ihren layout.js- oder page.js-Komponenten zu rendern. Beispiel:

app/products/[id]/page.tsx
TypeScript
export default async function Page({ params }) {
  const product = await getProduct(params.id)
 
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name: product.name,
    image: product.image,
    description: product.description,
  }
 
  return (
    <section>
      {/* JSON-LD zur Seite hinzufügen */}
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      {/* ... */}
    </section>
  )
}

Sie können Ihre strukturierten Daten mit dem Rich Results Test für Google oder dem generischen Schema Markup Validator validieren und testen.

Sie können Ihre JSON-LD mit TypeScript mit Community-Paketen wie schema-dts typisieren:

import { Product, WithContext } from 'schema-dts'
 
const jsonLd: WithContext<Product> = {
  '@context': 'https://schema.org',
  '@type': 'Product',
  name: 'Next.js Sticker',
  image: 'https://nextjs.org/imgs/sticker.png',
  description: 'Dynamisch mit der Geschwindigkeit von statisch.',
}