generateMetadata
此页面涵盖了使用 generateMetadata
和静态元数据对象的所有基于配置的元数据选项。
import type { Metadata } from 'next'
// either Static metadata
export const metadata: Metadata = {
title: '...',
}
// or Dynamic metadata
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
须知:
metadata
对象和generateMetadata
函数导出仅在服务器组件中受支持。- 你不能从同一路由段导出
metadata
对象和generateMetadata
函数。
metadata
对象
要定义静态元数据,从 layout.js
或 page.js
文件导出一个 Metadata
对象。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}
请参阅 元数据字段 以获取受支持选项的完整列表。
generateMetadata
函数
动态元数据取决于动态信息,例如当前路由参数、外部数据或父段中的 metadata
,可以通过导出一个返回 Metadata
对象的 generateMetadata
函数来设置。
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> {
// read route params
const id = (await params).id
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// optionally access and extend (rather than replace) parent metadata
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) {}
参数
generateMetadata
函数接受以下参数
-
props
- 一个包含当前路由参数的对象-
params
- 一个包含从根段到调用generateMetadata
的段的动态路由参数对象的对象。示例路由 URL params
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
- 一个包含当前 URL 的 搜索参数的对象。示例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
- 来自父路由段的已解析元数据的 Promise。
返回值
generateMetadata
应该返回一个包含一个或多个元数据字段的 Metadata
对象。
须知:
- 如果元数据不依赖于运行时信息,则应使用静态
metadata
对象 而不是generateMetadata
来定义。- 对于跨
generateMetadata
、generateStaticParams
、布局、页面和服务器组件的相同数据,fetch
请求会自动记忆化。如果fetch
不可用,可以使用 Reactcache
。searchParams
仅在page.js
段中可用。- Next.js 的
redirect()
和notFound()
方法也可以在generateMetadata
内部使用。
元数据字段
title
title
属性用于设置文档的标题。它可以定义为简单的字符串或可选的模板对象。
字符串
export const metadata = {
title: 'Next.js',
}
<title>Next.js</title>
模板对象
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '...',
default: '...',
absolute: '...',
},
}
默认值
title.default
可用于为未定义 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>
模板
title.template
可用于向子路由段中定义的 titles
添加前缀或后缀。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // a default is required when creating a template
},
}
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About',
}
// Output: <title>About | Acme</title>
须知:
title.template
应用于子路由段,而不是定义它的段。这意味着
- 当添加
title.template
时,title.default
是必需的。- 在
layout.js
中定义的title.template
将不适用于在同一路由段的page.js
中定义的title
。- 在
page.js
中定义的title.template
没有效果,因为页面始终是终止段(它没有任何子路由段)。如果路由未定义
title
或title.default
,则title.template
无效。
绝对
title.absolute
可用于提供一个忽略父段中设置的 title.template
的标题。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
},
}
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
absolute: 'About',
},
}
// Output: <title>About</title>
须知:
layout.js
title
(字符串)和title.default
定义子段(未定义自己的title
)的默认标题。如果存在,它将增强来自最近父段的title.template
。title.absolute
定义子段的默认标题。它忽略来自父段的title.template
。title.template
为子段定义了一个新的标题模板。
page.js
- 如果页面未定义自己的标题,则将使用最近父级解析的标题。
title
(字符串)定义路由的标题。如果存在,它将增强来自最近父段的title.template
。title.absolute
定义路由标题。它忽略来自父段的title.template
。title.template
在page.js
中无效,因为页面始终是路由的终止段。
description
export const metadata = {
description: 'The React Framework for the Web',
}
<meta name="description" content="The React Framework for the Web" />
基本字段
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.net.cn' }],
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.net.cn" />
<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
是一个便捷选项,用于为需要完全限定 URL 的 metadata
字段设置基本 URL 前缀。
metadataBase
允许在当前路由段及以下定义的基于 URL 的metadata
字段使用相对路径,而不是原本需要的绝对 URL。- 字段的相对路径将与
metadataBase
组合以形成完全限定的 URL。 - 如果未配置,
metadataBase
将自动填充默认值。
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" />
须知:
metadataBase
通常在根app/layout.js
中设置,以应用于所有路由中基于 URL 的metadata
字段。- 所有需要绝对 URL 的基于 URL 的
metadata
字段都可以使用metadataBase
选项进行配置。metadataBase
可以包含子域名,例如https://app.acme.com
或基本路径,例如https://acme.com/start/from/here
- 如果
metadata
字段提供绝对 URL,则metadataBase
将被忽略。- 在未配置
metadataBase
的情况下,在基于 URL 的metadata
字段中使用相对路径将导致构建错误。- Next.js 将规范化
metadataBase
(例如https://acme.com/
)和相对字段(例如/path
)之间的重复斜杠为单个斜杠(例如https://acme.com/path
)
默认值
如果未配置,metadataBase
具有默认值。
在 Vercel 上
- 对于生产部署,将使用
VERCEL_PROJECT_PRODUCTION_URL
。- 对于预览部署,
VERCEL_BRANCH_URL
将优先,如果不存在,则回退到VERCEL_URL
。如果这些值存在,它们将用作
metadataBase
的默认值,否则回退到https://127.0.0.1:${process.env.PORT || 3000}
。这允许 Open Graph 图像在本地构建以及 Vercel 预览和生产部署上工作。当覆盖默认值时,我们建议使用环境变量来计算 URL。这允许为本地开发、暂存和生产环境配置 URL。有关这些环境变量的更多详细信息,请参阅 系统环境变量 文档。
URL 组成
URL 组成优先考虑开发者意图,而不是默认目录遍历语义。
metadataBase
和metadata
字段之间的尾部斜杠被规范化。metadata
字段中的“绝对”路径(通常会替换整个 URL 路径)被视为“相对”路径(从metadataBase
的末尾开始)。
例如,给定以下 metadataBase
import type { Metadata } from 'next'
export const metadata: Metadata = {
metadataBase: new URL('https://acme.com'),
}
任何继承上述 metadataBase
并设置其自身值的 metadata
字段都将按如下方式解析
metadata 字段 | 已解析 URL |
---|---|
/ | 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.net.cn',
siteName: 'Next.js',
images: [
{
url: 'https://nextjs.net.cn/og.png', // Must be an absolute URL
width: 800,
height: 600,
},
{
url: 'https://nextjs.net.cn/og-alt.png', // Must be an absolute URL
width: 1800,
height: 1600,
alt: 'My custom alt',
},
],
videos: [
{
url: 'https://nextjs.net.cn/video.mp4', // Must be an absolute URL
width: 800,
height: 600,
},
],
audio: [
{
url: 'https://nextjs.net.cn/audio.mp3', // Must be an absolute URL
},
],
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.net.cn/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image" content="https://nextjs.net.cn/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image" content="https://nextjs.net.cn/og-alt.png" />
<meta property="og:image:width" content="1800" />
<meta property="og:image:height" content="1600" />
<meta property="og:image:alt" content="My custom alt" />
<meta property="og:video" content="https://nextjs.net.cn/video.mp4" />
<meta property="og:video:width" content="800" />
<meta property="og:video:height" content="600" />
<meta property="og:audio" content="https://nextjs.net.cn/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" />
须知:
- 对于 Open Graph 图像,使用基于文件的元数据 API 可能更方便。基于文件的 API 将自动为你生成正确的元数据,而无需将配置导出与实际文件同步。
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
须知:我们建议尽可能使用基于文件的元数据 API 来处理图标。基于文件的 API 将自动为你生成正确的元数据,而无需将配置导出与实际文件同步。
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"
/>
须知:
msapplication-*
元标签在 Microsoft Edge 的 Chromium 构建版本中不再受支持,因此不再需要。
themeColor
已弃用:
metadata
中的themeColor
选项已在 Next.js 14 中弃用。请改用viewport
配置。
colorScheme
已弃用:
metadata
中的colorScheme
选项已在 Next.js 14 中弃用。请改用viewport
配置。
manifest
Web 应用程序清单,如 Web Application Manifest 规范 中所定义。
export const metadata = {
manifest: 'https://nextjs.net.cn/manifest.json',
}
<link rel="manifest" href="https://nextjs.net.cn/manifest.json" />
twitter
Twitter 规范(令人惊讶地)不仅用于 X(以前称为 Twitter)。
了解更多关于 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.net.cn/og.png'], // Must be an absolute URL
},
}
<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.net.cn/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.net.cn/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.net.cn/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
已弃用:
metadata
中的viewport
选项已在 Next.js 14 中弃用。请改用viewport
配置。
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.net.cn',
languages: {
'en-US': 'https://nextjs.net.cn/en-US',
'de-DE': 'https://nextjs.net.cn/de-DE',
},
media: {
'only screen and (max-width: 600px)': 'https://nextjs.net.cn/mobile',
},
types: {
'application/rss+xml': 'https://nextjs.net.cn/rss',
},
},
}
<link rel="canonical" href="https://nextjs.net.cn" />
<link rel="alternate" hreflang="en-US" href="https://nextjs.net.cn/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://nextjs.net.cn/de-DE" />
<link
rel="alternate"
media="only screen and (max-width: 600px)"
href="https://nextjs.net.cn/mobile"
/>
<link
rel="alternate"
type="application/rss+xml"
href="https://nextjs.net.cn/rss"
/>
appLinks
export const metadata = {
appLinks: {
ios: {
url: 'https://nextjs.net.cn/ios',
app_store_id: 'app_store_id',
},
android: {
package: 'com.example.android/package',
app_name: 'app_name_android',
},
web: {
url: 'https://nextjs.net.cn/web',
should_fallback: true,
},
},
}
<meta property="al:ios:url" content="https://nextjs.net.cn/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.net.cn/web" />
<meta property="al:web:should_fallback" content="true" />
archives
描述历史意义的记录、文档或其他材料的集合 (来源)。
export const metadata = {
archives: ['https://nextjs.net.cn/13'],
}
<link rel="archives" href="https://nextjs.net.cn/13" />
assets
export const metadata = {
assets: ['https://nextjs.net.cn/assets'],
}
<link rel="assets" href="https://nextjs.net.cn/assets" />
bookmarks
export const metadata = {
bookmarks: ['https://nextjs.net.cn/13'],
}
<link rel="bookmarks" href="https://nextjs.net.cn/13" />
category
export const metadata = {
category: 'technology',
}
<meta name="category" content="technology" />
facebook
您可以将 Facebook 应用程序或 Facebook 帐户连接到您的网页,以便用于某些 Facebook 社交插件 Facebook 文档
须知:您可以指定 appId 或 admins,但不能同时指定两者。
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" />
如果您想生成多个 fb:admins meta 标签,可以使用数组值。
export const metadata = {
facebook: {
admins: ['12345678', '87654321'],
},
}
<meta property="fb:admins" content="12345678" />
<meta property="fb:admins" content="87654321" />
other
所有元数据选项都应使用内置支持进行涵盖。但是,可能存在特定于您的网站或品牌的自定义元数据标签,或者刚刚发布的新元数据标签。您可以使用 other
选项来渲染任何自定义元数据标签。
export const metadata = {
other: {
custom: 'meta',
},
}
<meta name="custom" content="meta" />
如果您想生成多个具有相同键的 meta 标签,可以使用数组值。
export const metadata = {
other: {
custom: ['meta1', 'meta2'],
},
}
<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />
不支持的元数据
以下元数据类型目前没有内置支持。但是,它们仍然可以在布局或页面本身中渲染。
元数据 | 建议 |
---|---|
<meta http-equiv="..."> | 通过 redirect() 、中间件、安全标头 使用适当的 HTTP 标头 |
<base> | 在布局或页面本身中渲染标签。 |
<noscript> | 在布局或页面本身中渲染标签。 |
<style> | 了解更多关于 Next.js 中的样式。 |
<script> | 了解更多关于 使用脚本。 |
<link rel="stylesheet" /> | 直接在布局或页面本身中 import 样式表。 |
<link rel="preload /> | 使用 ReactDOM preload 方法 |
<link rel="preconnect" /> | 使用 ReactDOM preconnect 方法 |
<link rel="dns-prefetch" /> | 使用 ReactDOM prefetchDNS 方法 |
资源提示
<link>
元素有许多 rel
关键字,可用于提示浏览器可能需要外部资源。浏览器使用此信息根据关键字应用预加载优化。
虽然 Metadata API 不直接支持这些提示,但您可以使用新的 ReactDOM
方法 将它们安全地插入到文档的 <head>
中。
'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return '...'
}
<link rel="preload">
在页面渲染(浏览器)生命周期的早期开始加载资源。MDN 文档。
ReactDOM.preload(href: string, options: { as: string })
<link rel="preload" href="..." as="..." />
<link rel="preconnect">
抢先启动与来源的连接。MDN 文档。
ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })
<link rel="preconnect" href="..." crossorigin />
<link rel="dns-prefetch">
尝试在请求资源之前解析域名。MDN 文档。
ReactDOM.prefetchDNS(href: string)
<link rel="dns-prefetch" href="..." />
须知:
- 这些方法目前仅在客户端组件中受支持,客户端组件在初始页面加载时仍为服务器端渲染。
- Next.js 内置功能(如
next/font
、next/image
和next/script
)会自动处理相关的资源提示。
类型
您可以使用 Metadata
类型为您的元数据添加类型安全性。如果您在 IDE 中使用 内置的 TypeScript 插件,则无需手动添加类型,但如果您愿意,仍然可以显式添加它。
metadata
对象
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
generateMetadata
函数
常规函数
import type { Metadata } from 'next'
export function generateMetadata(): Metadata {
return {
title: 'Next.js',
}
}
异步函数
import type { Metadata } from 'next'
export async function generateMetadata(): Promise<Metadata> {
return {
title: 'Next.js',
}
}
使用分段 props
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) {}
使用父级元数据
import type { Metadata, ResolvingMetadata } from 'next'
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
return {
title: 'Next.js',
}
}
JavaScript 项目
对于 JavaScript 项目,您可以使用 JSDoc 添加类型安全性。
/** @type {import("next").Metadata} */
export const metadata = {
title: 'Next.js',
}
流式元数据
从 v15.2 开始,generateMetadata
返回的元数据将流式传输到客户端。这允许 Next.js 在元数据解析后立即将其注入到 HTML 中。
由于页面元数据通常主要针对机器人和爬虫,因此 Next.js 将继续阻止渲染,直到 HTML 受限机器人 的元数据解析完成。
某些机器人(如 Googlebot
)可以执行 JavaScript 并能够检查完整的页面 DOM,这意味着它们不需要阻塞元数据。但是,像 Twitterbot
这样的机器人无法在爬取页面时执行 JavaScript,它们属于 HTML 受限 类别。
Next.js 会自动检测传入请求的用户代理,以确定是提供流式元数据还是回退到阻塞元数据。
如果您需要自定义此列表,您可以使用 next.config.js
中的 htmlLimitedBots
选项手动定义它们。Next.js 将确保当请求您的网页时,与此正则表达式匹配的用户代理收到阻塞元数据。指定 htmlLimitedBots
配置将覆盖 Next.js 的默认列表,使您可以完全控制哪些用户代理应选择此行为。这是高级行为,默认设置对于大多数情况应该足够了。
module.exports = {
htmlLimitedBots: 'MySpecialBot|MyAnotherSpecialBot|SimpleCrawler',
}
注意: Next.js 包括 HTML 受限机器人的默认列表
版本历史
版本 | 变更 |
---|---|
v15.2.0 | 为 generateMetadata 引入了流式传输支持。 |
v13.2.0 | viewport 、themeColor 和 colorScheme 已弃用,转而使用 viewport 配置。 |
v13.2.0 | 引入了 metadata 和 generateMetadata 。 |
后续步骤
这篇文章对您有帮助吗?