元数据和 OG 图片
元数据 API 可用于定义应用程序元数据,以改善 SEO 和网络共享性,包括
- 静态
metadata对象 - 动态
generateMetadata函数 - 可用于添加静态或动态生成的网站图标和OG 图像的特殊文件约定。
通过上述所有选项,Next.js 将自动为您的页面生成相关的 <head> 标签,可以在浏览器的开发工具中进行检查。
metadata 对象和 generateMetadata 函数导出仅在服务器组件中受支持。
默认字段
即使路由未定义元数据,也会始终添加两个默认的 meta 标签
- meta charset 标签设置网站的字符编码。
- meta viewport 标签设置网站的视口宽度和比例,以适应不同的设备。
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />其他元数据字段可以使用 Metadata 对象(用于静态元数据)或 generateMetadata 函数(用于生成的元数据)进行定义。
静态元数据
要定义静态元数据,请从静态 layout.js 或 page.js 文件中导出 Metadata 对象。例如,要向博客路由添加标题和描述
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'My Blog',
description: '...',
}
export default function Layout() {}您可以在generateMetadata 文档中查看可用选项的完整列表。
生成的元数据
您可以使用 generateMetadata 函数来 fetch 依赖于数据的元数据。例如,要获取特定博客文章的标题和描述
import type { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: Promise<{ slug: string }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
const slug = (await params).slug
// fetch post information
const post = await fetch(`https://api.vercel.app/blog/${slug}`).then((res) =>
res.json()
)
return {
title: post.title,
description: post.description,
}
}
export default function Page({ params, searchParams }: Props) {}流式元数据
对于动态渲染的页面,Next.js 会单独流式传输元数据,一旦 generateMetadata 解析,就会将其注入 HTML,而不会阻塞 UI 渲染。
流式元数据通过允许视觉内容首先流式传输来提高感知性能。
流式元数据已为需要元数据位于 <head> 标签中的机器人和爬虫(例如 Twitterbot、Slackbot、Bingbot)**禁用**。这些机器人和爬虫通过传入请求的用户代理标头进行检测。
您可以使用 Next.js 配置文件中的 htmlLimitedBots 选项来完全自定义或**禁用**流式元数据。
静态渲染的页面不使用流式传输,因为元数据在构建时解析。
了解更多关于流式元数据的信息。
记忆化数据请求
在某些情况下,您可能需要为元数据和页面本身获取**相同**的数据。为了避免重复请求,您可以使用 React 的 cache 函数 来记忆返回值,只获取一次数据。例如,要为元数据和页面获取博客文章信息
import { cache } from 'react'
import { db } from '@/app/lib/db'
// getPost will be used twice, but execute only once
export const getPost = cache(async (slug: string) => {
const res = await db.query.posts.findFirst({ where: eq(posts.slug, slug) })
return res
})import { getPost } from '@/app/lib/data'
export async function generateMetadata({
params,
}: {
params: { slug: string }
}) {
const post = await getPost(params.slug)
return {
title: post.title,
description: post.description,
}
}
export default async function Page({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug)
return <div>{post.title}</div>
}基于文件的元数据
以下特殊文件可用于元数据
- favicon.ico、apple-icon.jpg 和 icon.jpg
- opengraph-image.jpg 和 twitter-image.jpg
- robots.txt
- sitemap.xml
您可以将这些用于静态元数据,也可以使用代码以编程方式生成这些文件。
网站图标
网站图标是代表您网站在书签和搜索结果中的小图标。要为您的应用程序添加网站图标,请创建 favicon.ico 并将其添加到 app 文件夹的根目录。

您还可以使用代码以编程方式生成网站图标。有关更多信息,请参阅网站图标文档。
静态开放图谱图像
开放图谱 (OG) 图像是代表您网站在社交媒体中的图像。要为您的应用程序添加静态 OG 图像,请在 app 文件夹的根目录中创建 opengraph-image.png 文件。

您还可以通过在更深层的文件夹结构中创建 opengraph-image.png 来为特定路由添加 OG 图像。例如,要为 /blog 路由创建特定的 OG 图像,请在 blog 文件夹中添加一个 opengraph-image.jpg 文件。

更具体的图像将优先于文件夹结构中其上方的任何 OG 图像。
还支持其他图像格式,例如
jpeg、png和gif。有关更多信息,请参阅开放图谱图像文档。
生成的开放图谱图像
ImageResponse 构造函数允许您使用 JSX 和 CSS 生成动态图像。这对于依赖于数据的 OG 图像非常有用。
例如,要为每篇博客文章生成唯一的 OG 图像,请在 blog 文件夹中添加 opengraph-image.tsx 文件,并从 next/og 导入 ImageResponse 构造函数
import { ImageResponse } from 'next/og'
import { getPost } from '@/app/lib/data'
// Image metadata
export const size = {
width: 1200,
height: 630,
}
export const contentType = 'image/png'
// Image generation
export default async function Image({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug)
return new ImageResponse(
(
// ImageResponse JSX element
<div
style={{
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{post.title}
</div>
)
)
}ImageResponse 支持常见的 CSS 属性,包括 flexbox 和绝对定位、自定义字体、文本换行、居中和嵌套图像。查看支持的 CSS 属性的完整列表。
须知:
- 示例可在Vercel OG Playground中找到。
ImageResponse使用@vercel/og、satori和resvg将 HTML 和 CSS 转换为 PNG。- 仅支持 flexbox 和 CSS 属性的子集。高级布局(例如
display: grid)将不起作用。
API 参考
generateMetadata
generateViewport
ImageResponse
元数据文件
favicon、icon 和 apple-icon
opengraph-image 和 twitter-image
robots.txt
sitemap.xml
htmlLimitedBots
这有帮助吗?


