字节笔记本
2026年7月20日
Next.js Metadata API 完全指南:从基础配置到 SEO 最佳实践
Next.js Metadata API 完全指南:从基础配置到 SEO 最佳实践
网站的元数据(Metadata)直接影响搜索引擎排名和社交媒体分享效果。Next.js App Router 提供了一套完整的 Metadata API,让元数据管理变得简单高效。本文从实际开发角度,梳理 Next.js 中元数据配置的核心用法和常见陷阱。
两种配置方式
静态 metadata 对象
在 layout.js 或 page.js 中直接导出:
export const metadata = {
title: '我的 Next.js 网站',
description: '这是一个使用 Next.js 构建的现代化网站',
}Next.js 会自动生成对应的 HTML 标签:
<title>我的 Next.js 网站</title>
<meta name="description" content="这是一个使用 Next.js 构建的现代化网站" />动态 generateMetadata 函数
适合需要根据数据动态生成元数据的场景,比如商品详情页:
export async function generateMetadata({ params }) {
const product = await fetch(`https://api.example.com/products/${params.id}`)
.then(res => res.json())
return {
title: product.name,
description: product.description,
openGraph: {
images: [product.image],
},
}
}注意:generateMetadata 是一个异步函数,服务端渲染时自动调用,不需要在客户端处理。
标题模板:保持全站一致性
Next.js 支持标题模板,子页面只需提供页面名称,框架会自动拼接:
// app/layout.js
export const metadata = {
title: {
template: '%s | 网站名称',
default: '首页 | 网站名称',
}
}
// app/about/page.js
export const metadata = {
title: '关于我们'
}
// 最终生成:<title>关于我们 | 网站名称</title>模板机制的好处在于改一次 layout,全站标题格式统一更新。
OpenGraph 与 Twitter 卡片
社交媒体分享时的预览效果,取决于 OpenGraph 和 Twitter 卡片的配置:
export const metadata = {
openGraph: {
title: '页面标题',
description: '页面描述',
images: [{
url: 'https://example.com/og-image.jpg',
width: 1200,
height: 630,
alt: '预览图描述',
}],
locale: 'zh_CN',
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: '页面标题',
description: '页面简介',
images: ['https://example.com/twitter-image.jpg'],
}
}图片建议尺寸 1200x630,这是各大社交平台的主流预览尺寸。
JSON-LD 结构化数据
结构化数据帮助搜索引擎理解页面内容类型,对于文章、商品等页面尤为重要:
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: '文章标题',
description: '文章描述',
image: 'https://example.com/cover.jpg',
datePublished: '2024-11-05',
author: {
'@type': 'Person',
name: '作者名',
},
}
// 在页面中注入
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>可以通过 Google 的 Rich Results Test 验证结构化数据是否正确。
基于文件的元数据约定
Next.js 还支持通过文件命名自动生成元数据:
| 文件 | 用途 |
|---|---|
favicon.ico | 传统网站图标 |
icon.png | 现代浏览器图标 |
apple-icon.png | Apple 设备图标 |
robots.txt | 搜索引擎爬取规则 |
sitemap.xml | 站点地图 |
manifest.json | PWA 配置 |
只需要在 app 目录下放置对应文件,Next.js 自动处理,不需要手动写 meta 标签。
国际化场景的元数据
多语言网站需要配置 alternates,告诉搜索引擎不同语言版本的 URL:
export const metadata = {
alternates: {
languages: {
'en-US': '/en',
'zh-CN': '/zh',
'ja': '/ja',
}
}
}这样搜索引擎在展示搜索结果时,可以根据用户语言偏好展示对应的语言版本。
图标的多尺寸配置
export const metadata = {
icons: {
icon: [
{ url: '/icon-16.png', sizes: '16x16', type: 'image/png' },
{ url: '/icon-32.png', sizes: '32x32', type: 'image/png' },
{ url: '/icon-48.png', sizes: '48x48', type: 'image/png' },
],
apple: [
{ url: '/apple-icon-180.png', sizes: '180x180', type: 'image/png' },
],
}
}常见注意事项
1. metadata 对象中不能使用动态值
// 错误:metadata 导出时不能用变量
const title = '动态标题'
export const metadata = {
title: title, // 这个 title 是静态解析的
}
// 正确:用 generateMetadata
export async function generateMetadata() {
const title = await getTitle()
return { title }
}2. generateMetadata 和 generateStaticParams 配合
静态生成的页面,generateMetadata 会在构建时执行,可以放心做异步请求。
3. 不要重复定义
子页面的配置会覆盖父页面的同名配置。如果只想补充而不是覆盖,需要在子页面中重新声明完整的值。
Edge Runtime 与元数据
如果你的页面运行在 Edge Runtime 上,generateMetadata 同样可以正常工作。Edge Runtime 适合需要低延迟响应的全球化场景:
export const runtime = 'edge'
export async function generateMetadata({ params }) {
// 在边缘节点执行,延迟更低
const data = await fetch(`https://api.example.com/data/${params.id}`)
return {
title: data.title,
description: data.description,
}
}Edge Runtime 使用 V8 引擎和 Web APIs,不支持 Node.js 特有 API,但启动速度更快,适合轻量的动态元数据生成。
总结
Next.js Metadata API 的设计思路是「约定优于配置」加上「类型安全」。静态场景用 metadata 对象,动态场景用 generateMetadata 函数,配合标题模板和文件约定,可以高效管理全站元数据。配置好 OpenGraph、Twitter 卡片和 JSON-LD 后,社交媒体分享和搜索引擎收录都会有明显改善。