TDK + meta
TDK 是 Title、Description、Keywords 的缩写,是 SEO(搜索引擎优化)里的核心元信息,也常统称为页面的元数据。
在原生 HTML 里,它们大致对应 <head> 中的 <title>、<meta name="description">、<meta name="keywords"> 等。使用 App Router 时,Next.js 通过 export const metadata 或 generateMetadata 生成上述标签,由框架写入文档头部,无需手写整段 <head>。
TDK 的作用
title
title 是页面标题,通常会出现在浏览器标签页和搜索引擎结果页(SERP)上,对点击率影响最大 。建议简洁、准确,并体现当前页与站点/栏目的关系(例如与根布局的 title.template 搭配使用,见下文)。
description
description 是页面摘要,常被用作 SERP 中的描述文案(搜索引擎也可能根据内容自行改写)。应用一两句话概括页面价值,避免堆砌关键词。
keywords
keywords 用于概括页面主题。主流搜索引擎对 <meta name="keywords"> 的排序权重已很低,但规范填写仍有利于内部归类、CMS 或后续扩展;不要为 SEO 而重复、堆砌无意义词组。
书写上的小建议(实践向)
- title :不同页面应有区分度;全站共用的后缀可通过根布局的
title.template统一拼接。 - description:长度适中即可(常见建议约 150 字以内作参考),重点写清「这一页解决什么问题」。
- keywords:用数组表达多个词即可,与页面内容一致即可。
Next.js 中如何配置 TDK
我们使用 App Router ,一般在 app 目录下的根布局 layout.tsx 中导出 metadata,作为全站默认 TDK;子路由下的 layout.tsx / page.tsx 若再次导出 metadata,会对父级进行覆盖或按字段合并 (例如子页面的 title 会覆盖继承来的默认标题,具体以 Metadata 文档 为准)。
metadata 为静态对象,适合不依赖请求参数、不依赖异步接口数据的场景。
tsx
// app/layout.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: '小满优选',
description: '小满优选描述',
keywords: ['小满优选', '优选'],
};

子路由需要单独展示时,在对应 page.tsx(或该段的 layout.tsx) 中再导出一份 metadata 即可;未声明的字段会继续沿用祖先布局的配置。
根布局里还可以用 title.default + title.template,让子页面只写短标题、全站自动带上后缀,例如:
tsx
// app/layout.tsx(节选)
export const metadata: Metadata = {
title: {
default: '小满优选',
template: '%s | 小满优选',
},
description: '小满优选描述',
keywords: ['小满优选', '优选'],
};
子页面写 title: '首页' 时,在支持模板合并的情况下,浏览器标题可呈现为 首页 | 小满优选(具体以当前 Next 版本行为为准)。
tsx
// app/home/page.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: '首页',
description: '首页描述',
keywords: ['首页', '小满优选'],
};
export default function Page() {
return <div>首页</div>;
}

进阶:用 generateMetadata 动态配置 TDK
当标题、描述等需要依赖 动态路由参数 、查询参数 或 接口 / 数据库 时,在对应 page.tsx(或 layout.tsx)中导出异步函数 generateMetadata ,返回 Metadata 对象即可。它在服务端执行,可与页面数据使用同一套请求逻辑(注意缓存与性能,必要时配合 fetch 的缓存选项或数据层)。
参数说明
- 第一个参数
propsparams:动态路由段,例如app/posts/[id]/page.tsx中的id。searchParams:当前 URL 的查询参数,例如?id=123。
- 第二个参数
parent- 类型为
ResolvingMetadata,表示父级布局已解析的 metadata 。await parent后可用于拼接标题、继承openGraph图片等。
- 类型为
下面示例假定路由为 app/posts/[id]/page.tsx ,根据 id 请求文章并生成 TDK(接口仅为演示,可换成你的真实 API):
tsx
// app/posts/[id]/page.tsx
import type { Metadata, ResolvingMetadata } from 'next';
type Props = {
params: Promise<{ id: string }>;
};
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
const { id } = await params;
const resolvedParent = await parent;
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${id}`
);
if (!res.ok) {
return { title: '文章未找到' };
}
const data = await res.json();
return {
title: `${data.title} | ${resolvedParent.title?.absolute ?? '文章'}`,
description: data.body.slice(0, 150),
keywords: [data.title],
};
}
export default async function PostPage({ params }: Props) {
const { id } = await params;
return <div>文章 id:{id}</div>;
}
若还需根据 searchParams (例如 ?tab=reviews)切换描述,把函数第一个参数写为 { params, searchParams } 并在需要时同样 await searchParams 即可。
其他常用 Metadata(了解即可)
除 TDK 外,Metadata 还可配置 Open Graph 、Twitter Card 、robots 、站点图标 、添加到主屏幕(PWA)相关 等。配置 相对路径的图片 (如 OG 图)时,建议在根 metadata 中设置 metadataBase(站点根 URL),以便 Next 正确拼出绝对地址。
tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
metadataBase: new URL('https://example.com'),
title: '小满优选',
description: '小满优选描述',
keywords: ['小满优选', '优选'],
openGraph: {
title: '...',
description: '...',
type: 'website',
images: ['/og.png'],
},
twitter: {
card: 'summary_large_image',
title: '...',
description: '...',
images: ['/og.png'],
},
robots: {
index: true,
follow: true,
},
icons: {
icon: '/favicon.ico',
},
appleWebApp: {
capable: true,
title: '小满优选',
statusBarStyle: 'black-translucent',
},
};
Open Graph(OG)
Open Graph 是 Facebook(现 Meta)提出的一套页面元数据协议,通过 <meta property="og:*"> 描述标题、描述、封面图、类型等。当链接被分享到微信、Slack、Discord、LinkedIn 等平台时,抓取方会读取这些标签来生成卡片预览 ,因此 OG 与 SEO (点击率、品牌呈现)和 传播体验 都密切相关。
在 App Router 中,Next.js 通过导出 metadata 或 generateMetadata 中的 openGraph 字段,自动生成对应的 OG 标签,无需手写整段 <head>。官方说明见 Metadata API 与 Optimizing Metadata。
实例:苹果官网的 OG 标签与分享效果
下面这段是 Apple 官网 首页实际输出的部分 OG 元数据(与页面在浏览器「查看源代码」中可见的 og:* 一致;og:image 上的查询串常用于缓存版本控制,可按需更新):
html
<meta property="og:image" content="https://www.apple.com/ac/structured-data/images/open_graph_logo.png?202604211141" />
<meta property="og:title" content="Apple" />
<meta property="og:description" content="Discover the innovative world of Apple and shop everything iPhone, iPad, Apple Watch, Mac, and Apple TV, plus explore accessories, entertainment, and expert device support." />
<meta property="og:url" content="https://www.apple.com/" />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="Apple" />
<meta property="og:type" content="website" />
在微信里转发该链接时,客户端会按上述字段拼出链接卡片 :左侧一般为 og:image(此处为白底灰苹果 Logo),右侧为 og:title 粗体标题,其下为 og:description 摘要(各客户端会按自己的规则截断并加省略号)。

同一组信息在 Next.js 里可写成 Metadata['openGraph'](图片用绝对 URL 时不必依赖 metadataBase):
tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
openGraph: {
title: 'Apple',
description:
'Discover the innovative world of Apple and shop everything iPhone, iPad, Apple Watch, Mac, and Apple TV, plus explore accessories, entertainment, and expert device support.',
url: 'https://www.apple.com/',
siteName: 'Apple',
locale: 'en_US',
type: 'website',
images: [
{
url: 'https://www.apple.com/ac/structured-data/images/open_graph_logo.png?202604211141',
},
],
},
};
openGraph 能配置什么
在 Metadata 对象里的 openGraph 还支持视频、音频、多图、文章发布时间等。常用字段归纳如下:
| 配置项 | 典型用途 |
|---|---|
title / description |
卡片标题与摘要(可与页面 TDK 一致或单独优化分享文案) |
url |
规范链接,建议与当前页可访问 URL 一致 |
siteName |
站点名称 |
images |
预览图(可多图);常配宽高与 alt |
videos / audio |
富媒体预览(需绝对 URL) |
locale |
语言区域,如 en_US |
type |
资源类型,如 website;文章常用 article |
tsx
// app/layout.tsx 或任意 page.tsx / layout.tsx
import type { Metadata } from 'next';
export const metadata: 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',
width: 800,
height: 600,
},
{
url: 'https://nextjs.org/og-alt.png',
width: 1800,
height: 1600,
alt: 'My custom alt',
},
],
locale: 'en_US',
type: 'website',
},
};
文章类页面可设置 type: 'article',并配合 publishedTime、authors 等,框架会输出 article:* 系列属性(详见 官方 openGraph 小节)。
Open Graph 官网与 type 去哪查
如果你想确认协议原文或查 og:type 的语义,优先看 Open Graph 官方站点:
- 协议首页:
ogp.me type说明与扩展类型入口:ogp.me/#types- 已定义的对象类型列表(如
website、article、video.movie等):ogp.me/#structured
在 Next.js 项目里,openGraph.type 还受 Next 的 TypeScript 类型约束。你可以通过两种方式确认当前版本支持的值:
- 查看 Next.js 文档中的
openGraph字段示例与说明:generateMetadata#opengraph - 在编辑器里把鼠标悬停到
Metadata['openGraph']['type'](或跳转到next包类型定义)查看联合类型,以你项目安装的 Next 版本为准。
metadataBase 与相对路径
OG 图片等 URL 类字段 在多数场景下需要绝对地址 。根布局中设置 metadataBase 后,当前段及子路由里的相对路径会与基址拼接,避免到处写死域名:
tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
metadataBase: new URL('https://acme.com'),
openGraph: {
images: '/og-image.png',
},
};
若某字段已是完整 https://...,则不再套用 metadataBase。未配置 metadataBase 却在 URL 类元数据里使用相对路径,构建可能报错,这一点以你当前 Next.js 版本文档为准。
动态路由:generateMetadata 与父级 images
详情页等需要按参数拉数据时,使用 generateMetadata 。第二个参数 parent 可拿到父布局已解析的 metadata,便于在子页面追加 OG 图而不是整段覆盖,例如把当前商品图插到继承来的图片列表前面:
tsx
import type { Metadata, ResolvingMetadata } from 'next';
type Props = { params: Promise<{ id: string }> };
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
const { id } = await params;
const product = await fetch(`https://api.example.com/products/${id}`).then(
(r) => r.json()
);
const previousImages = (await parent).openGraph?.images || [];
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
};
}
同一数据请求在 generateMetadata 与页面 Server Component 之间会被 memoized ,避免重复打接口(见官方 generateMetadata 说明)。
基于文件的 OG 图(推荐场景)
单独维护「导出里的图片 URL」和「仓库里的真实文件」容易不同步。对 OG 图而言,更省事的做法是使用 基于文件的 Metadata ,例如在路由段放置 opengraph-image.png 或 opengraph-image.tsx 动态生成图,由框架生成正确 meta。详见 opengraph-image。
与布局继承的关系(简要)
子路由若导出 了自己的 openGraph 对象,会与父级按官方规则做合并或覆盖 ;若子段完全不设置 openGraph,则继续沿用祖先布局的配置。具体嵌套行为以 Metadata 字段与继承 为准。
实践建议
- 一图多用 :分享图尺寸需符合各平台建议(常见如 1200×630 等),并保持主体在安全区内,避免裁切后信息丢失。品牌站也可用苹果这种方形 Logo 图,在部分客户端里会以缩略图形式出现。
- 与 TDK 协调 :
openGraph.title/openGraph.description可与metadata.title、metadata.description相同,也可为分享单独写更「点击率友好」的短文案。 - 验证:改完后用各平台提供的调试/预览工具(如部分平台提供的 URL 调试器)拉取一次,确认缓存更新后再对外发链接。
更多字段与 HTML 对照表仍以 Next.js 官网 openGraph 为准。