Metadata-Objekt und generateMetadata-Optionen

Diese Seite behandelt alle konfigurationsbasierten Metadaten-Optionen mit generateMetadata und dem statischen Metadata-Objekt.

import { Metadata } from 'next'

// Entweder statische Metadaten
export const metadata: Metadata = {
  title: '...',
}

// Oder dynamische Metadaten
export async function generateMetadata({ params }) {
  return {
    title: '...',
  }
}
// Entweder statische Metadaten
export const metadata = {
  title: '...',
}

// Oder dynamische Metadaten
export async function generateMetadata({ params }) {
  return {
    title: '...',
  }
}

Gut zu wissen:

  • Das metadata-Objekt und die generateMetadata-Funktion werden nur in Server Components unterstützt.
  • Sie können nicht gleichzeitig das metadata-Objekt und die generateMetadata-Funktion aus demselben Routensegment exportieren.

Das metadata-Objekt

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

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: '...',
  description: '...',
}

export default function Page() {}
export const metadata = {
  title: '...',
  description: '...',
}

export default function Page() {}

Eine vollständige Liste der unterstützten Optionen finden Sie unter Metadata-Felder.

generateMetadata-Funktion

Dynamische Metadaten, die von dynamischen Informationen abhängen, wie z.B. den aktuellen Routenparametern, externen Daten oder metadata in übergeordneten Segmenten, können durch Exportieren einer generateMetadata-Funktion festgelegt werden, die ein Metadata-Objekt zurückgibt.

import { Metadata, ResolvingMetadata } from 'next'

type Props = {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  // Routenparameter lesen
  const id = params.id

  // Daten abrufen
  const product = await fetch(`https://.../${id}`).then((res) => res.json())

  // Optional auf übergeordnete Metadaten zugreifen und erweitern (anstatt zu ersetzen)
  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) {}
export async function generateMetadata({ params, searchParams }, parent) {
  // Routenparameter lesen
  const id = params.id

  // Daten abrufen
  const product = await fetch(`https://.../${id}`).then((res) => res.json())

  // Optional auf übergeordnete Metadaten zugreifen und erweitern (anstatt zu ersetzen)
  const previousImages = (await parent).openGraph?.images || []

  return {
    title: product.title,
    openGraph: {
      images: ['/some-specific-page-image.jpg', ...previousImages],
    },
  }
}

export default function Page({ params, searchParams }) {}

Parameter

Die generateMetadata-Funktion akzeptiert folgende Parameter:

  • props - Ein Objekt mit den Parametern der aktuellen Route:

    • params - Ein Objekt mit den dynamischen Routenparametern vom Wurzelsegment bis zu dem Segment, aus dem generateMetadata aufgerufen wird. Beispiele:

      RouteURLparams
      app/shop/[slug]/page.js/shop/1{ slug: '1' }
      app/shop/[tag]/[item]/page.js/shop/1/2{ tag: '1', item: '2' }
      app/shop/[...slug]/page.js/shop/1/2{ slug: ['1', '2'] }
    • searchParams - Ein Objekt mit den Suchparametern der aktuellen URL. Beispiele:

      URLsearchParams
      /shop?a=1{ a: '1' }
      /shop?a=1&b=2{ a: '1', b: '2' }
      /shop?a=1&a=2{ a: ['1', '2'] }
  • parent - Ein Promise der aufgelösten Metadaten aus übergeordneten Routensegmenten.

Rückgabewert

generateMetadata sollte ein Metadata-Objekt zurückgeben, das ein oder mehrere Metadatenfelder enthält.

Gut zu wissen:

  • Wenn Metadaten nicht von Laufzeitinformationen abhängen, sollten sie mit dem statischen metadata-Objekt definiert werden, nicht mit generateMetadata.
  • fetch-Anfragen werden automatisch memoisiert für dieselben Daten über generateMetadata, generateStaticParams, Layouts, Seiten und Server Components hinweg. React cache kann verwendet werden, wenn fetch nicht verfügbar ist.
  • searchParams sind nur in page.js-Segmenten verfügbar.
  • Die Next.js-Methoden redirect() und notFound() können auch innerhalb von generateMetadata verwendet werden.

Metadata-Felder

title

Das title-Attribut wird verwendet, um den Titel des Dokuments festzulegen. Es kann als einfache Zeichenkette oder als optionales Template-Objekt definiert werden.

Zeichenkette

layout.js | page.js
export const metadata = {
  title: 'Next.js',
}
<head> output
<title>Next.js</title>

Template-Objekt

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '...',
    default: '...',
    absolute: '...',
  },
}
export const metadata = {
  title: {
    default: '...',
    template: '...',
    absolute: '...',
  },
}
Default

title.default kann verwendet werden, um einen Fallback-Titel für untergeordnete Routensegmente bereitzustellen, die keinen title definieren.

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

export const metadata: Metadata = {
  title: {
    default: 'Acme',
  },
}
app/about/page.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {}

// Ausgabe: <title>Acme</title>
Template

title.template kann verwendet werden, um titles in untergeordneten Routensegmenten ein Präfix oder Suffix hinzuzufügen.

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
    default: 'Acme', // Ein Default ist erforderlich, wenn ein Template erstellt wird
  },
}
export const metadata = {
  title: {
    template: '%s | Acme',
    default: 'Acme', // Ein Default ist erforderlich, wenn ein Template erstellt wird
  },
}
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'About',
}

// Ausgabe: <title>About | Acme</title>
export const metadata = {
  title: 'About',
}

// Ausgabe: <title>About | Acme</title>

Gut zu wissen:

  • title.template gilt für untergeordnete Routensegmente und nicht für das Segment, in dem es definiert ist. Das bedeutet:

    • title.default ist erforderlich, wenn Sie ein title.template hinzufügen.
    • title.template, das in layout.js definiert ist, gilt nicht für einen title, der in einer page.js desselben Routensegments definiert ist.
    • title.template, das in page.js definiert ist, hat keine Wirkung, da eine Seite immer das abschließende Segment ist (sie hat keine untergeordneten Routensegmente).
  • title.template hat keine Wirkung, wenn eine Route keinen title oder title.default definiert hat.

Absolute

title.absolute kann verwendet werden, um einen Titel bereitzustellen, der title.template in übergeordneten Segmenten ignoriert.

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
  },
}
export const metadata = {
  title: {
    template: '%s | Acme',
  },
}
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    absolute: 'About',
  },
}

// Ausgabe: <title>About</title>
export const metadata = {
  title: {
    absolute: 'About',
  },
}

// Ausgabe: <title>About</title>

Gut zu wissen:

  • layout.js

    • title (Zeichenkette) und title.default definieren den Standardtitel für untergeordnete Segmente (die keinen eigenen title definieren). Es wird title.template vom nächsten übergeordneten Segment ergänzen, falls vorhanden.
    • title.absolute definiert den Standardtitel für untergeordnete Segmente. Es ignoriert title.template von übergeordneten Segmenten.
    • title.template definiert eine neue Titelvorlage für untergeordnete Segmente.
  • page.js

    • Wenn eine Seite keinen eigenen Titel definiert, wird der aufgelöste Titel des nächsten übergeordneten Segments verwendet.
    • title (Zeichenkette) definiert den Titel der Route. Es wird title.template vom nächsten übergeordneten Segment ergänzen, falls vorhanden.
    • title.absolute definiert den Titel der Route. Es ignoriert title.template von übergeordneten Segmenten.
    • title.template hat in page.js keine Wirkung, da eine Seite immer das abschließende Segment einer Route ist.

description

layout.js | page.js
export const metadata = {
  description: 'The React Framework for the Web',
}
<head> output
<meta name="description" content="The React Framework for the Web" />

Grundlegende Felder

layout.js | page.js
export const metadata = {
  generator: 'Next.js',
  applicationName: 'Next.js',
  referrer: 'origin-when-cross-origin',
  keywords: ['Next.js', 'React', 'JavaScript'],
  authors: [{ name: 'Seb' }, { name: 'Josh', url: 'https://nextjs.org' }],
  creator: 'Jiachi Liu',
  publisher: 'Sebastian Markbåge',
  formatDetection: {
    email: false,
    address: false,
    telephone: false,
  },
}
<head> output
<meta name="application-name" content="Next.js" />
<meta name="author" content="Seb" />
<link rel="author" href="https://nextjs.org" />
<meta name="author" content="Josh" />
<meta name="generator" content="Next.js" />
<meta name="keywords" content="Next.js,React,JavaScript" />
<meta name="referrer" content="origin-when-cross-origin" />
<meta name="color-scheme" content="dark" />
<meta name="creator" content="Jiachi Liu" />
<meta name="publisher" content="Sebastian Markbåge" />
<meta name="format-detection" content="telephone=no, address=no, email=no" />

metadataBase

metadataBase ist eine praktische Option, um einen Basis-URL-Präfix für metadata-Felder festzulegen, die eine vollständig qualifizierte URL erfordern.

  • metadataBase ermöglicht es URL-basierten metadata-Feldern, die im aktuellen Routensegment und darunter definiert sind, einen relativen Pfad anstelle einer ansonsten erforderlichen absoluten URL zu verwenden.
  • Der relative Pfad des Felds wird mit metadataBase kombiniert, um eine vollständig qualifizierte URL zu bilden.
  • Wenn nicht konfiguriert, wird metadataBase automatisch mit einem Standardwert gefüllt.
layout.js | page.js
export const metadata = {
  metadataBase: new URL('https://acme.com'),
  alternates: {
    canonical: '/',
    languages: {
      'en-US': '/en-US',
      'de-DE': '/de-DE',
    },
  },
  openGraph: {
    images: '/og-image.png',
  },
}
<head> output
<link rel="canonical" href="https://acme.com" />
<link rel="alternate" hreflang="en-US" href="https://acme.com/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://acme.com/de-DE" />
<meta property="og:image" content="https://acme.com/og-image.png" />

Gut zu wissen:

  • metadataBase wird typischerweise in der Root-app/layout.js gesetzt, um auf URL-basierte metadata-Felder über alle Routen hinweg anzuwenden.
  • Alle URL-basierten metadata-Felder, die absolute URLs erfordern, können mit einer metadataBase-Option konfiguriert werden.
  • metadataBase kann eine Subdomain enthalten, z.B. https://app.acme.com oder einen Basispfad, z.B. https://acme.com/start/from/here
  • Wenn ein metadata-Feld eine absolute URL bereitstellt, wird metadataBase ignoriert.
  • Die Verwendung eines relativen Pfads in einem URL-basierten metadata-Feld ohne Konfiguration von metadataBase führt zu einem Build-Fehler.
  • Next.js normalisiert doppelte Schrägstriche zwischen metadataBase (z.B. https://acme.com/) und einem relativen Feld (z.B. /path) zu einem einfachen Schrägstrich (z.B. https://acme.com/path)

Standardwert

Wenn nicht konfiguriert, hat metadataBase einen Standardwert

  • Wenn VERCEL_URL erkannt wird: https://${process.env.VERCEL_URL, andernfalls wird auf http://localhost:${process.env.PORT || 3000} zurückgegriffen.
  • Beim Überschreiben des Standardwerts empfehlen wir die Verwendung von Umgebungsvariablen, um die URL zu berechnen. Dies ermöglicht die Konfiguration einer URL für lokale Entwicklung, Staging und Produktionsumgebungen.

URL-Zusammensetzung

Die URL-Zusammensetzung bevorzugt die Absicht des Entwicklers gegenüber der Standardverzeichnistraversierungssemantik.

  • Schrägstriche zwischen metadataBase und metadata-Feldern werden normalisiert.
  • Ein "absoluter" Pfad in einem metadata-Feld (der normalerweise den gesamten URL-Pfad ersetzen würde) wird als "relativer" Pfad behandelt (beginnend am Ende von metadataBase).

Beispielsweise, gegeben den folgenden metadataBase:

import { Metadata } from 'next'

export const metadata: Metadata = {
  metadataBase: new URL('https://acme.com'),
}
export const metadata = {
  metadataBase: new URL('https://acme.com'),
}

Alle metadata-Felder, die den obigen metadataBase erben und ihren eigenen Wert setzen, werden wie folgt aufgelöst:

metadata-FeldAufgelöste URL
/https://acme.com
./https://acme.com
paymentshttps://acme.com/payments
/paymentshttps://acme.com/payments
./paymentshttps://acme.com/payments
../paymentshttps://acme.com/payments
https://beta.acme.com/paymentshttps://beta.acme.com/payments

openGraph

layout.js | page.js
export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'Das React-Framework für das Web',
    url: 'https://nextjs.org',
    siteName: 'Next.js',
    images: [
      {
        url: 'https://nextjs.org/og.png', // Muss eine absolute URL sein
        width: 800,
        height: 600,
      },
      {
        url: 'https://nextjs.org/og-alt.png', // Muss eine absolute URL sein
        width: 1800,
        height: 1600,
        alt: 'Mein benutzerdefinierter Alt-Text',
      },
    ],
    videos: [
      {
        url: 'https://nextjs.org/video.mp4', // Muss eine absolute URL sein
        width: 800,
        height: 600,
      },
    ],
    audio: [
      {
        url: 'https://nextjs.org/audio.mp3', // Muss eine absolute URL sein
      },
    ],
    locale: 'en_US',
    type: 'website',
  },
}
<head> output
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="Das React-Framework für das Web" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image:url" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image:url" content="https://nextjs.org/og-alt.png" />
<meta property="og:image:width" content="1800" />
<meta property="og:image:height" content="1600" />
<meta property="og:image:alt" content="Mein benutzerdefinierter Alt-Text" />
<meta property="og:video" content="https://nextjs.org/video.mp4" />
<meta property="og:video:width" content="800" />
<meta property="og:video:height" content="600" />
<meta property="og:audio" content="https://nextjs.org/audio.mp3" />
<meta property="og:type" content="website" />
layout.js | page.js
export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'Das React-Framework für das Web',
    type: 'article',
    publishedTime: '2023-01-01T00:00:00.000Z',
    authors: ['Seb', 'Josh'],
  },
}
<head> output
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="Das React-Framework für das Web" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-01-01T00:00:00.000Z" />
<meta property="article:author" content="Seb" />
<meta property="article:author" content="Josh" />

Gut zu wissen:

  • Für Open-Graph-Bilder kann die dateibasierte Metadata API praktischer sein. Anstatt die Konfiguration mit den tatsächlichen Dateien synchron halten zu müssen, generiert die dateibasierte API automatisch die korrekten Metadaten.

robots

import type { Metadata } from 'next'

export const metadata: Metadata = {
  robots: {
    index: false,
    follow: true,
    nocache: true,
    googleBot: {
      index: true,
      follow: false,
      noimageindex: true,
      'max-video-preview': -1,
      'max-image-preview': 'large',
      'max-snippet': -1,
    },
  },
}
<head> output
<meta name="robots" content="noindex, follow, nocache" />
<meta
  name="googlebot"
  content="index, nofollow, noimageindex, max-video-preview:-1, max-image-preview:large, max-snippet:-1"
/>

icons

Gut zu wissen: Wir empfehlen die Verwendung der dateibasierten Metadata API für Icons, wo möglich. Anstatt die Konfiguration mit den tatsächlichen Dateien synchron halten zu müssen, generiert die dateibasierte API automatisch die korrekten Metadaten.

layout.js | page.js
export const metadata = {
  icons: {
    icon: '/icon.png',
    shortcut: '/shortcut-icon.png',
    apple: '/apple-icon.png',
    other: {
      rel: 'apple-touch-icon-precomposed',
      url: '/apple-touch-icon-precomposed.png',
    },
  },
}
<head> output
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>
layout.js | page.js
export const metadata = {
  icons: {
    icon: [
      { url: '/icon.png' },
      new URL('/icon.png', 'https://example.com'),
      { url: '/icon-dark.png', media: '(prefers-color-scheme: dark)' },
    ],
    shortcut: ['/shortcut-icon.png'],
    apple: [
      { url: '/apple-icon.png' },
      { url: '/apple-icon-x3.png', sizes: '180x180', type: 'image/png' },
    ],
    other: [
      {
        rel: 'apple-touch-icon-precomposed',
        url: '/apple-touch-icon-precomposed.png',
      },
    ],
  },
}
<head> output
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="icon" href="https://example.com/icon.png" />
<link rel="icon" href="/icon-dark.png" media="(prefers-color-scheme: dark)" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>
<link
  rel="apple-touch-icon"
  href="/apple-icon-x3.png"
  sizes="180x180"
  type="image/png"
/>

Gut zu wissen: Die msapplication-* Meta-Tags werden in Chromium-basierten Versionen von Microsoft Edge nicht mehr unterstützt und sind daher nicht mehr notwendig.

themeColor

Veraltet: Die themeColor-Option in metadata ist seit Next.js 14 veraltet. Bitte verwenden Sie stattdessen die viewport-Konfiguration.

manifest

Ein Web-App-Manifest, wie in der Web Application Manifest Spezifikation definiert.

layout.js | page.js
export const metadata = {
  manifest: 'https://nextjs.org/manifest.json',
}
<head> output
<link rel="manifest" href="https://nextjs.org/manifest.json" />

twitter

Die Twitter-Spezifikation wird (überraschenderweise) für mehr als nur X (ehemals bekannt als Twitter) verwendet.

Mehr Informationen finden Sie in der Twitter Card Markup Referenz.

layout.js | page.js
export const metadata = {
  twitter: {
    card: 'summary_large_image',
    title: 'Next.js',
    description: 'Das React-Framework für das Web',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: ['https://nextjs.org/og.png'], // Muss eine absolute URL sein
  },
}
<head> output
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="Das React-Framework für das Web" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
layout.js | page.js
export const metadata = {
  twitter: {
    card: 'app',
    title: 'Next.js',
    description: 'Das React-Framework für das Web',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: {
      url: 'https://nextjs.org/og.png',
      alt: 'Next.js Logo',
    },
    app: {
      name: 'twitter_app',
      id: {
        iphone: 'twitter_app://iphone',
        ipad: 'twitter_app://ipad',
        googleplay: 'twitter_app://googleplay',
      },
      url: {
        iphone: 'https://iphone_url',
        ipad: 'https://ipad_url',
      },
    },
  },
}
<head> output
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="Das React-Framework für das Web" />
<meta name="twitter:card" content="app" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
<meta name="twitter:image:alt" content="Next.js Logo" />
<meta name="twitter:app:name:iphone" content="twitter_app" />
<meta name="twitter:app:id:iphone" content="twitter_app://iphone" />
<meta name="twitter:app:id:ipad" content="twitter_app://ipad" />
<meta name="twitter:app:id:googleplay" content="twitter_app://googleplay" />
<meta name="twitter:app:url:iphone" content="https://iphone_url" />
<meta name="twitter:app:url:ipad" content="https://ipad_url" />
<meta name="twitter:app:name:ipad" content="twitter_app" />
<meta name="twitter:app:name:googleplay" content="twitter_app" />

viewport

Veraltet: Die viewport-Option in metadata ist seit Next.js 14 veraltet. Bitte verwenden Sie stattdessen die viewport-Konfiguration.

verification

layout.js | page.js
export const metadata = {
  verification: {
    google: 'google',
    yandex: 'yandex',
    yahoo: 'yahoo',
    other: {
      me: ['my-email', 'my-link'],
    },
  },
}
<head> output
<meta name="google-site-verification" content="google" />
<meta name="y_key" content="yahoo" />
<meta name="yandex-verification" content="yandex" />
<meta name="me" content="my-email" />
<meta name="me" content="my-link" />

appleWebApp

layout.js | page.js
export const metadata = {
  itunes: {
    appId: 'myAppStoreID',
    appArgument: 'myAppArgument',
  },
  appleWebApp: {
    title: 'Apple Web App',
    statusBarStyle: 'black-translucent',
    startupImage: [
      '/assets/startup/apple-touch-startup-image-768x1004.png',
      {
        url: '/assets/startup/apple-touch-startup-image-1536x2008.png',
        media: '(device-width: 768px) and (device-height: 1024px)',
      },
    ],
  },
}
<head> output
<meta
  name="apple-itunes-app"
  content="app-id=myAppStoreID, app-argument=myAppArgument"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Apple Web App" />
<link
  href="/assets/startup/apple-touch-startup-image-768x1004.png"
  rel="apple-touch-startup-image"
/>
<link
  href="/assets/startup/apple-touch-startup-image-1536x2008.png"
  media="(device-width: 768px) and (device-height: 1024px)"
  rel="apple-touch-startup-image"
/>
<meta
  name="apple-mobile-web-app-status-bar-style"
  content="black-translucent"
/>

alternates

layout.js | page.js
export const metadata = {
  alternates: {
    canonical: 'https://nextjs.org',
    languages: {
      'en-US': 'https://nextjs.org/en-US',
      'de-DE': 'https://nextjs.org/de-DE',
    },
    media: {
      'only screen and (max-width: 600px)': 'https://nextjs.org/mobile',
    },
    types: {
      'application/rss+xml': 'https://nextjs.org/rss',
    },
  },
}
<head> output
<link rel="canonical" href="https://nextjs.org" />
<link rel="alternate" hreflang="en-US" href="https://nextjs.org/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://nextjs.org/de-DE" />
<link
  rel="alternate"
  media="only screen and (max-width: 600px)"
  href="https://nextjs.org/mobile"
/>
<link
  rel="alternate"
  type="application/rss+xml"
  href="https://nextjs.org/rss"
/>
layout.js | page.js
export const metadata = {
  appLinks: {
    ios: {
      url: 'https://nextjs.org/ios',
      app_store_id: 'app_store_id',
    },
    android: {
      package: 'com.example.android/package',
      app_name: 'app_name_android',
    },
    web: {
      url: 'https://nextjs.org/web',
      should_fallback: true,
    },
  },
}
<head> output
<meta property="al:ios:url" content="https://nextjs.org/ios" />
<meta property="al:ios:app_store_id" content="app_store_id" />
<meta property="al:android:package" content="com.example.android/package" />
<meta property="al:android:app_name" content="app_name_android" />
<meta property="al:web:url" content="https://nextjs.org/web" />
<meta property="al:web:should_fallback" content="true" />

archives

Beschreibt eine Sammlung von Aufzeichnungen, Dokumenten oder anderen Materialien von historischem Interesse (Quelle).

layout.js | page.js
export const metadata = {
  archives: ['https://nextjs.org/13'],
}
<head> output
<link rel="archives" href="https://nextjs.org/13" />

assets

layout.js | page.js
export const metadata = {
  assets: ['https://nextjs.org/assets'],
}
<head> output
<link rel="assets" href="https://nextjs.org/assets" />

bookmarks

layout.js | page.js
export const metadata = {
  bookmarks: ['https://nextjs.org/13'],
}
<head> output
<link rel="bookmarks" href="https://nextjs.org/13" />

category

layout.js | page.js
export const metadata = {
  category: 'technology',
}
<head> output
<meta name="category" content="technology" />

facebook

Sie können eine Facebook-App oder ein Facebook-Konto mit Ihrer Webseite verbinden, um bestimmte Facebook Social Plugins zu nutzen Facebook-Dokumentation

Gut zu wissen: Sie können entweder appId oder admins angeben, aber nicht beides.

layout.js | page.js
export const metadata = {
  facebook: {
    appId: '12345678',
  },
}
<head> output
<meta property="fb:app_id" content="12345678" />
layout.js | page.js
export const metadata = {
  facebook: {
    admins: '12345678',
  },
}
<head> output
<meta property="fb:admins" content="12345678" />

Wenn Sie mehrere fb:admins Meta-Tags generieren möchten, können Sie einen Array-Wert verwenden.

layout.js | page.js
export const metadata = {
  facebook: {
    admins: ['12345678', '87654321'],
  },
}
<head> output
<meta property="fb:admins" content="12345678" />
<meta property="fb:admins" content="87654321" />

other

Alle Metadaten-Optionen sollten durch die integrierte Unterstützung abgedeckt sein. Es kann jedoch sein, dass es benutzerdefinierte Metadaten-Tags gibt, die spezifisch für Ihre Seite sind, oder brandneue Metadaten-Tags, die gerade veröffentlicht wurden. Sie können die other-Option verwenden, um beliebige benutzerdefinierte Metadaten-Tags zu rendern.

layout.js | page.js
export const metadata = {
  other: {
    custom: 'meta',
  },
}
<head> output
<meta name="custom" content="meta" />

Wenn Sie mehrere Meta-Tags mit demselben Schlüssel generieren möchten, können Sie einen Array-Wert verwenden.

layout.js | page.js
export const metadata = {
  other: {
    custom: ['meta1', 'meta2'],
  },
}
<head> output
<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />

Nicht unterstützte Metadaten

Die folgenden Metadatentypen werden derzeit nicht nativ unterstützt. Sie können jedoch weiterhin im Layout oder auf der Seite selbst gerendert werden.

MetadatenEmpfehlung
<meta http-equiv="...">Verwenden Sie geeignete HTTP-Header über redirect(), Middleware oder Sicherheits-Header
<base>Rendern Sie das Tag direkt im Layout oder auf der Seite.
<noscript>Rendern Sie das Tag direkt im Layout oder auf der Seite.
<style>Erfahren Sie mehr über Styling in Next.js.
<script>Erfahren Sie mehr über die Verwendung von Skripten.
<link rel="stylesheet" />Importieren Sie Stylesheets direkt im Layout oder auf der Seite.
<link rel="preload />Verwenden Sie die ReactDOM preload-Methode
<link rel="preconnect" />Verwenden Sie die ReactDOM preconnect-Methode
<link rel="dns-prefetch" />Verwenden Sie die ReactDOM prefetchDNS-Methode

Resource Hints

Das <link>-Element bietet eine Reihe von rel-Schlüsselwörtern, die dem Browser signalisieren, dass eine externe Ressource wahrscheinlich benötigt wird. Der Browser nutzt diese Informationen, um Vorab-Ladeoptimierungen anzuwenden.

Während die Metadata API diese Hints nicht direkt unterstützt, können Sie neue ReactDOM-Methoden verwenden, um sie sicher in den <head> des Dokuments einzufügen.

'use client'

import ReactDOM from 'react-dom'

export function PreloadResources() {
  ReactDOM.preload('...', { as: '...' })
  ReactDOM.preconnect('...', { crossOrigin: '...' })
  ReactDOM.prefetchDNS('...')

  return null
}
'use client'

import ReactDOM from 'react-dom'

export function PreloadResources() {
  ReactDOM.preload('...', { as: '...' })
  ReactDOM.preconnect('...', { crossOrigin: '...' })
  ReactDOM.prefetchDNS('...')

  return null
}

Lädt eine Ressource früh im Seitenrendering-Prozess (Browser) vor. MDN Docs.

ReactDOM.preload(href: string, options: { as: string })
<head> output
<link rel="preload" href="..." as="..." />

Initiiert präemptiv eine Verbindung zu einem Origin. MDN Docs.

ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })
<head> output
<link rel="preconnect" href="..." crossorigin />

Versucht, einen Domainnamen aufzulösen, bevor Ressourcen angefordert werden. MDN Docs.

ReactDOM.prefetchDNS(href: string)
<head> output
<link rel="dns-prefetch" href="..." />

Wissenswert:

  • Diese Methoden werden derzeit nur in Client Components unterstützt, die beim ersten Seitenaufruf serverseitig gerendert werden.
  • Integrierte Next.js-Funktionen wie next/font, next/image und next/script handhaben relevante Resource Hints automatisch.
  • React 18.3 enthält noch keine Typdefinitionen für ReactDOM.preload, ReactDOM.preconnect und ReactDOM.preconnectDNS. Sie können // @ts-ignore als temporäre Lösung verwenden, um Typfehler zu vermeiden.

Typen

Sie können Typsicherheit für Ihre Metadaten hinzufügen, indem Sie den Metadata-Typ verwenden. Wenn Sie das integrierte TypeScript-Plugin in Ihrer IDE verwenden, müssen Sie den Typ nicht manuell hinzufügen, können dies aber dennoch explizit tun.

metadata-Objekt

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Next.js',
}

generateMetadata-Funktion

Reguläre Funktion

import type { Metadata } from 'next'

export function generateMetadata(): Metadata {
  return {
    title: 'Next.js',
  }
}

Async-Funktion

import type { Metadata } from 'next'

export async function generateMetadata(): Promise<Metadata> {
  return {
    title: 'Next.js',
  }
}

Mit Segment-Props

import type { Metadata } from 'next'

type Props = {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}

export function generateMetadata({ params, searchParams }: Props): Metadata {
  return {
    title: 'Next.js',
  }
}

export default function Page({ params, searchParams }: Props) {}

Mit übergeordneten Metadaten

import type { Metadata, ResolvingMetadata } from 'next'

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  return {
    title: 'Next.js',
  }
}

JavaScript-Projekte

Für JavaScript-Projekte können Sie JSDoc verwenden, um Typsicherheit hinzuzufügen.

/** @type {import("next").Metadata} */
export const metadata = {
  title: 'Next.js',
}

Versionsverlauf

VersionÄnderungen
v13.2.0viewport, themeColor und colorScheme wurden zugunsten der viewport-Konfiguration als veraltet markiert.
v13.2.0metadata und generateMetadata wurden eingeführt.