2.6 元数据与 SEO(Metadata & SEO)


2.6 元数据与 SEO(Metadata & SEO)

本节摘要:内容型网站的命脉是搜索引擎收录。Next.js 的 Metadata API 让你在组件里声明页面的 title、description、OG 标签、结构化数据。本节讲清静态与动态元数据、generateMetadata 的用法、sitemap 与 robots 的生成,以及 SEO 的核心实践。

读前必看

阅读完本节,你应当能够:

  1. 用 export const metadata 设置静态元数据
  2. 用 generateMetadata 动态生成(读取路由参数)
  3. 配置 Open Graph 社交分享标签
  4. 生成 sitemap 与 robots.txt
  5. 建立"页面级 SEO"的思维

问题与直觉:为什么 SEO 是 Next.js 的核心卖点

搜索引擎爬虫看到的是HTML 源码。纯 React(CSR)的源码是空壳,爬虫拿不到内容;Next.js 默认服务器渲染,源码里就有完整内容与 title/description——这是 Next.js 在内容型网站领域碾压纯 SPA 的根本原因。

直觉类比:SEO 像"图书馆编目"——title 是书名、description 是内容简介、OG 标签是"社交平台上的封面"。编目做得好,用户(搜索引擎/社交平台)才愿意展示你的页面。

💡 关键直觉:Metadata API 是"声明式 SEO"——不用手动写 <head> 里的 title/meta 标签,在组件里导出 metadata 对象,Next.js 自动注入到 HTML 头部,SSR 渲染时爬虫就能读到。

核心原理:Metadata API

2.1 静态元数据

// app/about/page.tsx import type { Metadata } from "next"; export const metadata: Metadata = { title: "关于我们 | 我的网站", description: "介绍我们的团队与使命", keywords: ["Next.js", "React", "全栈"], }; export default function AboutPage() { return <h1>关于我们</h1>; }

title 模板:在根布局定义统一后缀:

// app/layout.tsx export const metadata: Metadata = { title: { default: "我的网站", template: "%s | 我的网站", // 子页面 title 自动加后缀 }, description: "网站描述", };

2.2 动态元数据:generateMetadata

需要读取路由参数/数据后生成:

// app/posts/[slug]/page.tsx import type { Metadata } from "next"; export async function generateMetadata({ params, }: { params: Promise<{ slug: string }>; }): Promise<Metadata> { const { slug } = await params; const post = await getPost(slug); // 按 slug 取文章 return { title: post.title, description: post.excerpt, }; }

关键:generateMetadata 在服务器运行,可以访问数据——每篇文章自动拥有自己的 title/description。

2.3 Open Graph:社交分享

export const metadata: Metadata = { title: "文章标题", openGraph: { title: "文章标题", description: "分享到微信/推特时显示的描述", images: ["/og-image.png"], // 分享封面图 type: "article", }, twitter: { card: "summary_large_image", title: "文章标题", images: ["/og-image.png"], }, };

为什么重要:用户把链接发到微信/微博/推特时,展示卡片(标题+描述+图)而非裸链接——分享转化率的隐形推手

工程实践要点:sitemap 与 robots

3.1 sitemap.ts:网站地图

// app/sitemap.ts import type { MetadataRoute } from "next"; export default function sitemap(): MetadataRoute.Sitemap { return [ { url: "https://example.com", lastModified: new Date() }, { url: "https://example.com/about", lastModified: new Date() }, { url: "https://example.com/blog", lastModified: new Date() }, ]; }

动态数据(文章列表)可生成完整 sitemap——告诉搜索引擎"你有哪些页面"。

3.2 robots.ts

// app/robots.ts import type { MetadataRoute } from "next"; export default function robots(): MetadataRoute.Robots { return { rules: [ { userAgent: "*", allow: "/", disallow: ["/admin/", "/api/"] }, ], sitemap: "https://example.com/sitemap.xml", }; }

控制爬虫可访问范围,避免后台被收录。

3.3 SEO 核心实践清单

项目 做法
每个页面有独立 title/description metadata 或 generateMetadata
语义化 HTML 用 h1/h2、article、nav 标签
图片有 alt 无障碍 + 图片 SEO
结构化数据 JSON-LD(文章、产品、FAQ)
规范 URL canonical 防重复收录
响应式 移动优先(Google 标准)

常见误区与排查

误区 现象 正解
忘 export metadata 页面 title 是默认 每个页面导出 metadata
动态页面 title 固定 所有文章同标题 generateMetadata 按参数生成
忘设置 OG 分享无卡片 openGraph 配置
后台被收录 隐私泄露 robots 禁止 + noindex
sitemap 404 文件命名错 app/sitemap.ts 自动生成 /sitemap.xml

动手演练:博客页面的 SEO 完整配置

// app/posts/[slug]/page.tsx —— 完整 SEO import type { Metadata } from "next"; async function getPost(slug: string) { // 模拟取数据 return { title: `文章 ${slug}`, excerpt: "摘要内容", content: "正文..." }; } export async function generateMetadata({ params, }: { params: Promise<{ slug: string }>; }): Promise<Metadata> { const { slug } = await params; const post = await getPost(slug); return { title: post.title, description: post.excerpt, openGraph: { title: post.title, description: post.excerpt, type: "article", }, alternates: { canonical: `/posts/${slug}` }, }; } export default async function PostPage({ params, }: { params: Promise<{ slug: string }>; }) { const { slug } = await params; const post = await getPost(slug); return ( <article> <h1>{post.title}</h1> <p>{post.excerpt}</p> <div>{post.content}</div> </article> ); }

验证:访问文章页,右键查看网页源代码——title/description/OG/canonical 全部在 HTML 源码中(爬虫可见)——这就是 Next.js 的 SEO 优势落地

核心回顾

  • Metadata API:组件里导出 metadata,自动注入 HTML 头部。
  • title 模板:根布局定义 default/template,子页面自动加后缀。
  • generateMetadata:读取参数与数据,动态生成每页元数据。
  • Open Graph:社交分享卡片(标题+描述+封面图)。
  • sitemap/robots:app/sitemap.ts、app/robots.ts 自动生成。
  • SEO 清单:独立 title、语义化 HTML、alt、canonical、结构化数据。

深入理解:SEO 的完整工作流

页面元数据的生成流程

关键:generateMetadata 在服务器运行、可访问数据——每篇文章的标题、描述都按内容动态生成,而不是所有页面共用一个。

SEO 实践清单(进阶)

  1. 结构化数据(JSON-LD):告诉搜索引擎"这是文章/产品/FAQ",可获富媒体展示(评分星、面包屑);
export default function ArticlePage() { const jsonLd = { "@context": "https://schema.org", "@type": "Article", headline: post.title, datePublished: post.createdAt, author: { "@type": "Person", name: post.author.name }, }; return ( <> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> <article>{/* ... */}</article> </> ); }
  1. canonical 防重复:同一内容多 URL(排序参数、UTM)时声明标准地址;
  2. 分页 SEO:列表分页每页独立 title("第 2 页 - 博客"),rel=prev/next 关联;
  3. 404 优化:自定义 404 页(返回 404 状态码),引导回首页;
  4. 速度即 SEO:LCP/CLS 影响排名(3.4 性能),SEO 与性能一体两面。

一句话:SEO 不是"上线后做的事",而是"每个页面生成时就该带的属性"——Metadata API 让这件事成为组件声明的一部分,天然随代码演进。

常见问题速答

问:generateMetadata 和 metadata 能同时用吗?
同页面两者取其所需:有动态数据用 generateMetadata(覆盖静态),无数据用静态 metadata。generateMetadata 优先。

问:怎么看 SEO 是否生效?
访问页面后查看网页源代码(Ctrl+U),搜索 title、meta description、og: 标签是否在 HTML 中。爬虫看到的就是源码内容。

问:多语言站点 SEO 怎么做?
每个语言页面独立 URL(/zh、/en),generateMetadata 里配 alternates.languages(hreflang)告诉搜索引擎语言版本关系。

问:需要给每个页面都写 description 吗?
建议写。description 影响搜索结果的点击率(虽不直接影响排名)。没有时搜索引擎会截取正文,效果差。

问:sitemap 需要手动更新吗?
动态站点建议在 sitemap.ts 里从数据库生成文章列表,随内容自动更新;纯静态站点构建时生成一次即可。

一句话总结

SEO 的落地方式是"每个页面生成时自带元数据"——静态页面用 export metadata,动态页面用 generateMetadata(读取参数与数据)。再加 sitemap 与 robots,内容型网站的收录基础就齐了。验证方式:查看网页源码,title/description/OG 标签都在 HTML 里。

动手练习建议

做一个"文章列表 + 详情"的 SEO 完整配置:列表页用静态 metadata(带 title 模板后缀),详情页用 generateMetadata(从 URL 参数取文章数据生成 title/description/OG)。查看源码确认每个页面都有独立标签。再加 sitemap.ts(含动态文章 URL)与 robots.ts(禁止 admin 路径)。

进阶练习:在详情页加 JSON-LD 结构化数据(Article 类型),用 Google 的结构化数据测试工具验证;给分享场景配好 og:image,在微信开发者工具里预览分享卡片。SEO 不是玄学——每项配置都能在源码或工具里验证。

章节自测

能说出静态 metadata 与 generateMetadata 的适用场景区别吗?能说出 hreflang 的作用吗?能说出验证 SEO 生效的方法吗?全部答对,SEO 基础就掌握了。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U