generateMetadata
Vous pouvez utiliser l'objet metadata ou la fonction generateMetadata pour définir des métadonnées.
L'objet metadata
Pour définir des métadonnées statiques, exportez un objet Metadata depuis un fichier layout.js ou page.js.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}export const metadata = {
title: '...',
description: '...',
}
export default function Page() {}Consultez les Champs de métadonnées pour une liste complète des options prises en charge.
La fonction generateMetadata
Les métadonnées dynamiques, qui dépendent d'informations dynamiques telles que les paramètres de route actuels, des données externes ou les metadata des segments parents, peuvent être définies en exportant une fonction generateMetadata qui renvoie un objet Metadata.
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> {
// lire les paramètres de route
const { id } = await params
// récupérer les données
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// accéder et étendre (plutôt que remplacer) les métadonnées parentes
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) {
// lire les paramètres de route
const { id } = await params
// récupérer les données
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// accéder et étendre (plutôt que remplacer) les métadonnées parentes
const previousImages = (await parent).openGraph?.images || []
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
export default function Page({ params, searchParams }) {}Bon à savoir :
- Les métadonnées peuvent être ajoutées aux fichiers
layout.jsetpage.js.- Next.js résoudra automatiquement les métadonnées et créera les balises
<head>pertinentes pour la page.- Les exports de l'objet
metadataet de la fonctiongenerateMetadatasont uniquement pris en charge dans les composants serveur.- Vous ne pouvez pas exporter à la fois l'objet
metadataet la fonctiongenerateMetadatadepuis le même segment de route.- Les requêtes
fetchà l'intérieur degenerateMetadatasont automatiquement mémoïsées pour les mêmes données entregenerateMetadata,generateStaticParams, les Layouts, les Pages et les composants serveur.- La fonction React
cachepeut être utilisée sifetchn'est pas disponible.- Les métadonnées basées sur les fichiers ont une priorité plus élevée et écraseront l'objet
metadataet la fonctiongenerateMetadata.
Référence
Paramètres
La fonction generateMetadata accepte les paramètres suivants :
-
props- Un objet contenant les paramètres de la route actuelle :-
params- Un objet contenant les paramètres de route dynamiques depuis le segment racine jusqu'au segment oùgenerateMetadataest appelé. Exemples :Route URL paramsapp/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- Un objet contenant les paramètres de recherche de l'URL actuelle. Exemples :URL searchParams/shop?a=1{ a: '1' }/shop?a=1&b=2{ a: '1', b: '2' }/shop?a=1&a=2{ a: ['1', '2'] }
-
-
parent- Une promesse des métadonnées résolues des segments de route parents.
Valeur de retour
generateMetadata doit renvoyer un objet Metadata contenant un ou plusieurs champs de métadonnées.
Bon à savoir :
- Si les métadonnées ne dépendent pas d'informations dynamiques, elles doivent être définies en utilisant l'objet statique
metadataplutôt quegenerateMetadata.- Les requêtes
fetchsont automatiquement mémoïsées pour les mêmes données entregenerateMetadata,generateStaticParams, les Layouts, les Pages et les composants serveur. La fonction Reactcachepeut être utilisée sifetchn'est pas disponible.searchParamsest uniquement disponible dans les segmentspage.js.- Les méthodes Next.js
redirect()etnotFound()peuvent également être utilisées dansgenerateMetadata.
Champs de métadonnées
Les champs suivants sont pris en charge :
title
L'attribut title est utilisé pour définir le titre du document. Il peut être défini comme une simple chaîne de caractères ou un objet de modèle optionnel.
String
export const metadata = {
title: 'Next.js',
}<title>Next.js</title>default
title.default peut être utilisé pour fournir un titre de secours aux segments de route enfants qui ne définissent pas de title.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
default: 'Acme',
},
}import type { Metadata } from 'next'
export const metadata: Metadata = {}
// Output: <title>Acme</title>template
title.template peut être utilisé pour ajouter un préfixe ou un suffixe aux titles définis dans les segments de route enfants.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // un default est requis lors de la création d'un template
},
}export const metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // un default est requis lors de la création d'un template
},
}import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About',
}
// Output: <title>About | Acme</title>export const metadata = {
title: 'About',
}
// Output: <title>About | Acme</title>Bon à savoir :
title.templates'applique aux segments de route enfants et non au segment où il est défini. Cela signifie :
title.defaultest requis lorsque vous ajoutez untitle.template.title.templatedéfini danslayout.jsne s'appliquera pas à untitledéfini dans unpage.jsdu même segment de route.title.templatedéfini danspage.jsn'a aucun effet car une page est toujours le segment terminal (elle n'a pas de segments de route enfants).
title.templaten'a aucun effet si une route n'a pas défini detitleoutitle.default.
absolute
title.absolute peut être utilisé pour fournir un titre qui ignore le title.template défini dans les segments parents.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
},
}export const metadata = {
title: {
template: '%s | Acme',
},
}import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
absolute: 'About',
},
}
// Output: <title>About</title>export const metadata = {
title: {
absolute: 'About',
},
}
// Output: <title>About</title>Bon à savoir :
layout.js
title(string) ettitle.defaultdéfinissent le titre par défaut pour les segments enfants (qui ne définissent pas leur propretitle). Il augmentera letitle.templatedu segment parent le plus proche s'il existe.title.absolutedéfinit le titre par défaut pour les segments enfants. Il ignore letitle.templatedes segments parents.title.templatedéfinit un nouveau modèle de titre pour les segments enfants.
page.js
- Si une page ne définit pas son propre titre, le titre résolu du parent le plus proche sera utilisé.
title(string) définit le titre de la route. Il augmentera letitle.templatedu segment parent le plus proche s'il existe.title.absolutedéfinit le titre de la route. Il ignore letitle.templatedes segments parents.title.templaten'a aucun effet danspage.jscar une page est toujours le segment terminal d'une route.
description
export const metadata = {
description: 'The React Framework for the Web',
}<meta name="description" content="The React Framework for the Web" />Autres champs
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,
},
}<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 est une option pratique pour définir un préfixe d'URL de base pour les champs metadata qui nécessitent une URL complète.
metadataBasepermet aux champsmetadatabasés sur les URL définis dans le segment de route actuel et en dessous d'utiliser un chemin relatif au lieu d'une URL absolue autrement requise.- Le chemin relatif du champ sera combiné avec
metadataBasepour former une URL complète.
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',
},
}<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" />Bon à savoir :
metadataBaseest généralement défini dans le fichier racineapp/layout.jspour s'appliquer aux champsmetadatabasés sur les URL dans toutes les routes.- Tous les champs
metadatabasés sur les URL qui nécessitent des URL absolues peuvent être configurés avec une optionmetadataBase.metadataBasepeut contenir un sous-domaine, par exemplehttps://app.acme.comou un chemin de base, par exemplehttps://acme.com/start/from/here.- Si un champ
metadatafournit une URL absolue,metadataBasesera ignoré.- L'utilisation d'un chemin relatif dans un champ
metadatabasé sur les URL sans configurer demetadataBaseentraînera une erreur de build.- Next.js normalisera les barres obliques doubles entre
metadataBase(par exemplehttps://acme.com/) et un champ relatif (par exemple/path) en une seule barre oblique (par exemplehttps://acme.com/path).
Composition d'URL
La composition d'URL privilégie l'intention du développeur par rapport à la sémantique de parcours de répertoire par défaut.
- Les barres obliques finales entre
metadataBaseet les champsmetadatasont normalisées. - Un chemin "absolu" dans un champ
metadata(qui remplacerait normalement tout le chemin de l'URL) est traité comme un chemin "relatif" (commençant à partir de la fin demetadataBase).
Par exemple, avec le metadataBase suivant :
import type { Metadata } from 'next'
export const metadata: Metadata = {
metadataBase: new URL('https://acme.com'),
}export const metadata = {
metadataBase: new URL('https://acme.com'),
}Tous les champs metadata qui héritent du metadataBase ci-dessus et définissent leur propre valeur seront résolus comme suit :
Champ metadata | URL résolue |
|---|---|
/ | https://acme.com |
./ | https://acme.com |
payments | https://acme.com/payments |
/payments | https://acme.com/payments |
./payments | https://acme.com/payments |
../payments | https://acme.com/payments |
https://beta.acme.com/payments | https://beta.acme.com/payments |
openGraph
export const metadata = {
openGraph: {
title: 'Next.js',
description: 'The React Framework for the Web',
url: 'https://nextjs.org',
siteName: 'Next.js',
images: [
{
url: 'https://nextjs.org/og.png', // Doit être une URL absolue
width: 800,
height: 600,
},
{
url: 'https://nextjs.org/og-alt.png', // Doit être une URL absolue
width: 1800,
height: 1600,
alt: 'Mon texte alternatif personnalisé',
},
],
videos: [
{
url: 'https://nextjs.org/video.mp4', // Doit être une URL absolue
width: 800,
height: 600,
},
],
audio: [
{
url: 'https://nextjs.org/audio.mp3', // Doit être une URL absolue
},
],
locale: 'en_US',
type: 'website',
},
}<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the 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" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image" 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="Mon texte alternatif personnalisé" />
<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" />export const metadata = {
openGraph: {
title: 'Next.js',
description: 'The React Framework for the Web',
type: 'article',
publishedTime: '2023-01-01T00:00:00.000Z',
authors: ['Seb', 'Josh'],
},
}<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the 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" />Bon à savoir :
- Il peut être plus pratique d'utiliser l'API Metadata basée sur les fichiers pour les images Open Graph. Plutôt que de devoir synchroniser l'export de configuration avec des fichiers réels, l'API basée sur les fichiers générera automatiquement les métadonnées correctes pour vous.
robots
import type { Metadata } from 'next'
export const metadata: Metadata = {
robots: {
index: true,
follow: true,
nocache: false,
googleBot: {
index: true,
follow: true,
noimageindex: false,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
}<meta name="robots" content="index, follow" />
<meta
name="googlebot"
content="index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1"
/>icons
Bon à savoir : Nous recommandons d'utiliser l'API Metadata basée sur les fichiers pour les icônes lorsque c'est possible. Plutôt que de devoir synchroniser l'export de configuration avec des fichiers réels, l'API basée sur les fichiers générera automatiquement les métadonnées correctes pour vous.
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',
},
},
}<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"
/>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',
},
],
},
}<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"
/>Bon à savoir : Les balises meta
msapplication-*ne sont plus prises en charge dans les versions Chromium de Microsoft Edge, et ne sont donc plus nécessaires.
themeColor
Déprécié : L'option
themeColordansmetadataest dépréciée depuis Next.js 14. Veuillez utiliser la configurationviewportà la place.
colorScheme
Déprécié : L'option
colorSchemedansmetadataest dépréciée depuis Next.js 14. Veuillez utiliser la configurationviewportà la place.
manifest
Un manifeste d'application web, tel que défini dans la spécification Web Application Manifest.
export const metadata = {
manifest: 'https://nextjs.org/manifest.json',
}<link rel="manifest" href="https://nextjs.org/manifest.json" />twitter
La spécification Twitter est (étonnamment) utilisée pour plus que X (anciennement connu sous le nom de Twitter).
En savoir plus sur la référence du balisage Twitter Card.
export const metadata = {
twitter: {
card: 'summary_large_image',
title: 'Next.js',
description: 'The React Framework for the Web',
siteId: '1467726470533754880',
creator: '@nextjs',
creatorId: '1467726470533754880',
images: ['https://nextjs.org/og.png'], // Doit être une URL absolue
},
}<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="The React Framework for the Web" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />export const metadata = {
twitter: {
card: 'app',
title: 'Next.js',
description: 'The React Framework for the 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',
},
},
},
}<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="The React Framework for the 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
Déprécié : L'option
viewportdansmetadataest dépréciée depuis Next.js 14. Veuillez utiliser la configurationviewportà la place.
verification
export const metadata = {
verification: {
google: 'google',
yandex: 'yandex',
yahoo: 'yahoo',
other: {
me: ['my-email', 'my-link'],
},
},
}<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
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)',
},
],
},
}<meta
name="apple-itunes-app"
content="app-id=myAppStoreID, app-argument=myAppArgument"
/>
<meta name="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
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',
},
},
}<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"
/>appLinks
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,
},
},
}<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
Décrit une collection d'enregistrements, de documents ou d'autres matériaux d'intérêt historique (source).
export const metadata = {
archives: ['https://nextjs.org/13'],
}<link rel="archives" href="https://nextjs.org/13" />assets
export const metadata = {
assets: ['https://nextjs.org/assets'],
}<link rel="assets" href="https://nextjs.org/assets" />bookmarks
export const metadata = {
bookmarks: ['https://nextjs.org/13'],
}<link rel="bookmarks" href="https://nextjs.org/13" />category
export const metadata = {
category: 'technology',
}<meta name="category" content="technology" />facebook
Vous pouvez connecter une application Facebook ou un compte Facebook à votre page web pour certains Facebook Social Plugins Documentation Facebook
Bon à savoir : Vous pouvez spécifier soit appId, soit admins, mais pas les deux.
export const metadata = {
facebook: {
appId: '12345678',
},
}<meta property="fb:app_id" content="12345678" />export const metadata = {
facebook: {
admins: '12345678',
},
}<meta property="fb:admins" content="12345678" />Si vous souhaitez générer plusieurs balises meta fb:admins, vous pouvez utiliser une valeur de tableau.
export const metadata = {
facebook: {
admins: ['12345678', '87654321'],
},
}<meta property="fb:admins" content="12345678" />
<meta property="fb:admins" content="87654321" />pinterest
Vous pouvez activer ou désactiver les Pinterest Rich Pins sur votre page web.
export const metadata = {
pinterest: {
richPin: true,
},
}<meta name="pinterest-rich-pin" content="true" />other
Toutes les options de métadonnées devraient être couvertes par le support intégré. Cependant, il peut y avoir des balises meta personnalisées spécifiques à votre site, ou de nouvelles balises meta tout juste publiées. Vous pouvez utiliser l'option other pour rendre n'importe quelle balise meta personnalisée.
export const metadata = {
other: {
custom: 'meta',
},
}<meta name="custom" content="meta" />Si vous souhaitez générer plusieurs balises meta avec la même clé, vous pouvez utiliser une valeur de tableau.
export const metadata = {
other: {
custom: ['meta1', 'meta2'],
},
}<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />Métadonnées non prises en charge
Les types de métadonnées suivants ne sont actuellement pas pris en charge de manière intégrée. Cependant, ils peuvent toujours être rendus dans le layout ou la page elle-même.
Types
Vous pouvez ajouter une sécurité de typage à vos métadonnées en utilisant le type Metadata. Si vous utilisez le plugin TypeScript intégré dans votre IDE, vous n'avez pas besoin d'ajouter manuellement le type, mais vous pouvez toujours l'ajouter explicitement si vous le souhaitez.
Objet metadata
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}Fonction generateMetadata
Fonction régulière
import type { Metadata } from 'next'
export function generateMetadata(): Metadata {
return {
title: 'Next.js',
}
}Fonction asynchrone
import type { Metadata } from 'next'
export async function generateMetadata(): Promise<Metadata> {
return {
title: 'Next.js',
}
}Avec les propriétés de segment
import type { Metadata } from 'next'
type Props = {
params: Promise<{ id: string }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}
export function generateMetadata({ params, searchParams }: Props): Metadata {
return {
title: 'Next.js',
}
}
export default function Page({ params, searchParams }: Props) {}Avec les métadonnées parentes
import type { Metadata, ResolvingMetadata } from 'next'
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
return {
title: 'Next.js',
}
}Projets JavaScript
Pour les projets JavaScript, vous pouvez utiliser JSDoc pour ajouter une sécurité de typage.
/** @type {import("next").Metadata} */
export const metadata = {
title: 'Next.js',
}| Métadonnées | Recommandation |
|---|---|
<meta http-equiv="..."> | Utilisez les en-têtes HTTP appropriés via redirect(), Middleware, Security Headers |
<base> | Rendez la balise dans le layout ou la page elle-même. |
<noscript> | Rendez la balise dans le layout ou la page elle-même. |
<style> | En savoir plus sur le style dans Next.js. |
<script> | En savoir plus sur l'utilisation des scripts. |
<link rel="stylesheet" /> | importez les feuilles de style directement dans le layout ou la page elle-même. |
<link rel="preload /> | Utilisez la méthode preload de ReactDOM |
<link rel="preconnect" /> | Utilisez la méthode preconnect de ReactDOM |
<link rel="dns-prefetch" /> | Utilisez la méthode prefetchDNS de ReactDOM |
Indices de ressources
L'élément <link> a un certain nombre de mots-clés rel qui peuvent être utilisés pour indiquer au navigateur qu'une ressource externe est susceptible d'être nécessaire. Le navigateur utilise ces informations pour appliquer des optimisations de préchargement en fonction du mot-clé.
Bien que l'API Metadata ne prenne pas directement en charge ces indices, vous pouvez utiliser les nouvelles méthodes ReactDOM pour les insérer en toute sécurité dans le <head> du document.
'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return '...'
}'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return '...'
}<link rel="preload">
Commencez à charger une ressource tôt dans le cycle de rendu de la page (navigateur). Documentation MDN.
ReactDOM.preload(href: string, options: { as: string })<link rel="preload" href="..." as="..." /><link rel="preconnect">
Initiez de manière préemptive une connexion à une origine. Documentation MDN.
ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })<link rel="preconnect" href="..." crossorigin /><link rel="dns-prefetch">
Tentez de résoudre un nom de domaine avant que les ressources ne soient demandées. Documentation MDN.
ReactDOM.prefetchDNS(href: string)<link rel="dns-prefetch" href="..." />Bon à savoir :
- Ces méthodes sont actuellement uniquement prises en charge dans les composants clients, qui sont toujours rendus côté serveur lors du chargement initial de la page.
- Les fonctionnalités intégrées de Next.js telles que
next/font,next/imageetnext/scriptgèrent automatiquement les indices de ressources pertinents.
Comportement
Champs par défaut
Il y a deux balises meta par défaut qui sont toujours ajoutées même si une route ne définit pas de métadonnées :
- La balise meta charset définit l'encodage des caractères pour le site web.
- La balise meta viewport définit la largeur et l'échelle de la fenêtre d'affichage pour le site web afin de s'adapter à différents appareils.
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />Bon à savoir : Vous pouvez remplacer la balise meta
viewportpar défaut.
Streaming des métadonnées
Les métadonnées retournées par generateMetadata sont streamées vers le client. Cela permet à Next.js d'injecter les métadonnées dans le HTML dès qu'elles sont résolues.
Comme les métadonnées de page ciblent principalement les robots et les crawlers, Next.js streamera les métadonnées pour les robots capables d'exécuter JavaScript et d'inspecter le DOM complet de la page (par exemple Googlebot). Cependant, les métadonnées continueront à bloquer le rendu de la page pour les robots limités en HTML (par exemple Twitterbot) car ceux-ci ne peuvent pas exécuter JavaScript lors du crawl.
Next.js détecte automatiquement l'agent utilisateur des requêtes entrantes pour déterminer s'il faut servir des métadonnées en streaming ou revenir à des métadonnées bloquantes.
Si vous devez personnaliser cette liste, vous pouvez les définir manuellement en utilisant l'option htmlLimitedBots dans next.config.js. Next.js s'assurera que les agents utilisateurs correspondant à cette regex reçoivent des métadonnées bloquantes lors de la requête de votre page web.
import type { NextConfig } from 'next'
const config: NextConfig = {
htmlLimitedBots: /MySpecialBot|MyAnotherSpecialBot|SimpleCrawler/,
}
export default configmodule.exports = {
htmlLimitedBots: /MySpecialBot|MyAnotherSpecialBot|SimpleCrawler/,
}Spécifier une configuration htmlLimitedBots remplacera la liste par défaut de Next.js, vous permettant un contrôle total sur les agents utilisateurs qui doivent adopter ce comportement. Il s'agit d'un comportement avancé, et la valeur par défaut devrait suffire dans la plupart des cas.
Ordre
Les métadonnées sont évaluées dans l'ordre, en commençant par le segment racine jusqu'au segment le plus proche du segment final page.js. Par exemple :
app/layout.tsx(Layout racine)app/blog/layout.tsx(Layout imbriqué Blog)app/blog/[slug]/page.tsx(Page Blog)
Fusion
En suivant l'ordre d'évaluation, les objets Metadata exportés depuis plusieurs segments dans la même route sont fusionnés superficiellement pour former la sortie finale des métadonnées d'une route. Les clés en double sont remplacées en fonction de leur ordre.
Cela signifie que les métadonnées avec des champs imbriqués tels que openGraph et robots qui sont définis dans un segment précédent sont écrasés par le dernier segment qui les définit.
Écrasement des champs
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme est un...',
},
}export const metadata = {
title: 'Blog',
openGraph: {
title: 'Blog',
},
}
// Sortie :
// <title>Blog</title>
// <meta property="og:title" content="Blog" />Dans l'exemple ci-dessus :
titledeapp/layout.jsest remplacé partitledansapp/blog/page.js.- Tous les champs
openGraphdeapp/layout.jssont remplacés dansapp/blog/page.jscarapp/blog/page.jsdéfinit les métadonnéesopenGraph. Notez l'absence deopenGraph.description.
Si vous souhaitez partager certains champs imbriqués entre les segments tout en écrasant d'autres, vous pouvez les extraire dans une variable séparée :
export const openGraphImage = { images: ['http://...'] }import { openGraphImage } from './shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'Accueil',
},
}import { openGraphImage } from '../shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'À propos',
},
}Dans l'exemple ci-dessus, l'image OG est partagée entre app/layout.js et app/about/page.js tandis que les titres sont différents.
Héritage des champs
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme est un...',
},
}export const metadata = {
title: 'À propos',
}
// Sortie :
// <title>À propos</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acme est un..." />Notes
titledeapp/layout.jsest remplacé partitledansapp/about/page.js.- Tous les champs
openGraphdeapp/layout.jssont hérités dansapp/about/page.jscarapp/about/page.jsne définit pas les métadonnéesopenGraph.
Historique des versions
| Version | Changements |
|---|---|
v15.2.0 | Introduction du support du streaming pour generateMetadata. |
v13.2.0 | viewport, themeColor, et colorScheme dépréciés en faveur de la configuration viewport. |
v13.2.0 | metadata et generateMetadata introduits. |