TDK
2026年9月6日
TDK = Title、Description、Keywords,对应 <title>、<meta name="description">、<meta name="keywords">。App Router 导出 metadata 或 generateMetadata,框架写进 <head>,不必手拼整段。
各自干什么
- title:标签页和搜索结果标题,对点击率影响最大。每页要能区分开。
- description:结果页摘要。引擎可能改写,仍值得写清「这一页解决什么」。大约 150 字内作参考。
- keywords:主题词。主流引擎几乎不当排序信号,别堆砌;给自己 CMS / 内部分类用即可。
静态 metadata
根布局给默认值,子页面覆盖或按字段合并:
import type { Metadata } from "next";
export const metadata: Metadata = {
title: {
default: "技术博客",
template: "%s | 技术博客",
},
description: "按主题查阅学习笔记。",
keywords: ["Next.js", "笔记"],
};
tsx
子页只写 title: "首页" 时,完整标题常是 首页 | 技术博客。本站 Pages Router 用的是自定义 Seo 组件,效果同类。
generateMetadata
标题依赖 [id]、查询串或接口时:
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 parentMeta = await parent;
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
if (!res.ok) return { title: "未找到" };
const post = await res.json();
return {
title: post.title,
description: String(post.body).slice(0, 150),
keywords: [post.title],
};
}
tsx
parent 是祖先已经解析好的 metadata,可拿来拼站点名、继承 OG 图。同一请求在 generateMetadata 和页面组件之间会被 memo,不必打两遍。
还要读 ?tab= 时,把 searchParams 一并 await。
其它常用字段
相对路径的图要先设 metadataBase,才能拼出绝对地址:
export const metadata: Metadata = {
metadataBase: new URL("https://example.com"),
robots: { index: true, follow: true },
icons: { icon: "/favicon.ico" },
openGraph: { images: ["/og.png"] },
};
ts
openGraph、twitter、robots、PWA 相关下次几篇展开。先保证每页 title / description 不重复、不空。