主题
元数据和原始图
¥Metadata and OG images
元数据 API 可用于定义应用元数据,以改进 SEO 和 Web 可共享性,包括:
¥The Metadata APIs can be used to define your application metadata for improved SEO and web shareability and include:
可用于添加静态或动态生成的 favicons 和 原始图片 的特殊 文件约定。
¥Special file conventions that can be used to add static or dynamically generated favicons and OG images.
使用以上所有选项,Next.js 将自动为你的页面生成相关的 <head>
标签,你可以在浏览器的开发者工具中检查这些标签。
¥With all the options above, Next.js will automatically generate the relevant <head>
tags for your page, which can be inspected in the browser's developer tools.
默认字段
¥Default fields
即使路由未定义元数据,也始终会添加两个默认的 meta
标记:
¥There are two default meta
tags that are always added even if a route doesn't define metadata:
元字符集标签 设置网站的字符编码。
¥The meta charset tag sets the character encoding for the website.
元视口标签 设置网站的视口宽度和比例,以适应不同的设备。
¥The meta viewport tag sets the viewport width and scale for the website to adjust for different devices.
html
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
其他元数据字段可以使用 Metadata
对象(对于 静态元数据)或 generateMetadata
函数(对于 生成的元数据)定义。
¥The other metadata fields can be defined with the Metadata
object (for static metadata) or the generateMetadata
function (for generated metadata).
静态元数据
¥Static metadata
要定义静态元数据,请从静态 layout.js
或 page.js
文件中导出 Metadata
对象。例如,要为博客路由添加标题和描述:
¥To define static metadata, export a Metadata
object from a static layout.js
or page.js
file. For example, to add a title and description to the blog route:
tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'My Blog',
description: '...',
}
export default function Page() {}
jsx
export const metadata = {
title: 'My Blog',
description: '...',
}
export default function Page() {}
你可以在 生成元数据文档 中查看可用选项的完整列表。
¥You can view a full list of available options, in the generate metadata documentation.
生成的元数据
¥Generated metadata
你可以使用 generateMetadata
函数来 fetch
依赖于数据的元数据。例如,要获取特定博客文章的标题和描述:
¥You can use generateMetadata
function to fetch
metadata that depends on data. For example, to fetch the title and description for a specific blog post:
tsx
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> {
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) {}
jsx
export async function generateMetadata({ params, searchParams }, parent) {
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 }) {}
在后台,Next.js 会将元数据从 UI 中分离出来,并在解析后立即将其注入 HTML。
¥Behind-the-scenes, Next.js will stream metadata separately from the UI and inject the metadata into the HTML as soon as it's resolved.
内存数据请求
¥Memoizing data requests
在某些情况下,你可能需要为元数据和页面本身获取相同的数据。为避免重复请求,你可以使用 React 的 cache
功能 文件来记忆返回值,并且只获取一次数据。例如,要获取博客文章的元数据和页面信息:
¥There may be cases where you need to fetch the same data for metadata and the page itself. To avoid duplicate requests, you can use React's cache
function to memoize the return value and only fetch the data once. For example, to fetch the blog post information for both the metadata and the page:
tsx
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
})
jsx
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) => {
const res = await db.query.posts.findFirst({ where: eq(posts.slug, slug) })
return res
})
tsx
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>
}
jsx
import { getPost } from '@/app/lib/data'
export async function generateMetadata({ params }) {
const post = await getPost(params.slug)
return {
title: post.title,
description: post.description,
}
}
export default async function Page({ params }) {
const post = await getPost(params.slug)
return <div>{post.title}</div>
}
网站图标
¥Favicons
网站图标是在书签和搜索结果中代表你网站的小图标。要将网站图标添加到应用,请创建一个 favicon.ico
文件并将其添加到应用文件夹的根目录。
¥Favicons are small icons that represent your site in bookmarks and search results. To add a favicon to your application, create a favicon.ico
and add to the root of the app folder.

你还可以使用代码以编程方式生成网站图标。请参阅 网站图标文档 了解更多信息。
¥You can also programmatically generate favicons using code. See the favicon docs for more information.
静态 Open Graph 图片
¥Static Open Graph images
Open Graph (OG) 图片是在社交媒体中代表你网站的图片。要将静态原始图片添加到应用,请在应用文件夹的根目录中创建一个 opengraph-image.png
文件。
¥Open Graph (OG) images are images that represent your site in social media. To add a static OG image to your application, create a opengraph-image.png
file in the root of the app folder.

你还可以通过在文件夹结构更深层创建 opengraph-image.png
来为特定路由添加原始图片。例如,要创建特定于 /blog
路由的 OG 图片,请在 blog
文件夹中添加一个 opengraph-image.jpg
文件。
¥You can also add OG images for specific routes by creating a opengraph-image.png
deeper down the folder structure. For example, to create an OG image specific to the /blog
route, add a opengraph-image.jpg
file inside the blog
folder.

在文件夹结构中,更具体的图片将优先于其上方的任何原始图片。
¥The more specific image will take precedence over any OG images above it in the folder structure.
还支持其他图片格式,例如
jpeg
、png
和webp
。请参阅 Open Graph 图片文档 了解更多信息。¥Other image formats such as
jpeg
,png
, andwebp
are also supported. See the Open Graph Image docs for more information.
生成的 Open Graph 图片
¥Generated Open Graph images
ImageResponse
构造函数 允许你使用 JSX 和 CSS 生成动态图片。这对于依赖于数据的原始镜像非常有用。
¥The ImageResponse
constructor allows you to generate dynamic images using JSX and CSS. This is useful for OG images that depend on data.
例如,要为每篇博客文章生成唯一的 OG 图片,请在 blog
文件夹中添加一个 opengraph-image.ts
文件,并从 next/og
导入 ImageResponse
构造函数:
¥For example, to generate a unique OG image for each blog post, add a opengraph-image.ts
file inside the blog
folder, and import the ImageResponse
constructor from next/og
:
tsx
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>
)
)
}
jsx
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 }) {
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 属性的完整列表。
¥ImageResponse
supports common CSS properties including flexbox and absolute positioning, custom fonts, text wrapping, centering, and nested images. See the full list of supported CSS properties.
需要了解:
¥Good to know:
Vercel OG 在线运行 中提供了示例。
¥Examples are available in the Vercel OG Playground.
ImageResponse
使用 @vercel/og、Satori 和 Resvg 将 HTML 和 CSS 转换为 PNG。¥
ImageResponse
uses @vercel/og, Satori, and Resvg to convert HTML and CSS into PNG.仅支持 flexbox 和 CSS 属性的子集。高级布局(例如
display: grid
)将不起作用。¥Only flexbox and a subset of CSS properties are supported. Advanced layouts (e.g.
display: grid
) will not work.