Next.js SEO 指南:如何选择 SSG、SSR 或 ISR,设置元数据和规范链接,生成 sitemap.xml,用 webhook 驱动博客,并让 AI 爬虫读懂页面。

简而言之
Next.js 是最适合 SEO 的 React 框架之一,因为它向爬虫发送完整的 HTML,而不是一个空壳。想要获得排名,应预渲染内容页面(静态生成或 ISR),用 Metadata API 定义标题、描述和规范链接,从 app 目录生成 sitemap.xml 和 robots.txt,使用真正的链接和正确的状态码,并且不要把主要内容放在只在浏览器中运行的代码里,因为大多数 AI 爬虫不执行 JavaScript。
想深入了解?请询问
快速测验
SEO 适合您吗?该如何开始?
4 个简单问题,看看 Google 能否为您带来客户。
我们给您的建议
Sorank 是最适合您的解决方案
人们在搜索您卖的东西,而您可以等几个月:Sorank 找到合适的搜索词,撰写并发布文章,并帮您获得外链。
Next.js SEO 的核心在于为每条路由做出正确选择:哪些内容在服务器端渲染,哪些内容被缓存,哪些内容在任何脚本运行之前就出现在 HTML 中。Google 在 JavaScript SEO 基础知识中说明,它分三个阶段处理 JavaScript 应用(抓取、渲染、编入索引),并指出服务器端渲染或预渲染"仍然是个好主意"。Next.js 默认就是这样做的。本指南介绍 App Router(Next.js 13 及以上版本),并附有旧版 Pages Router 的说明。
是的。传统的客户端渲染 React 应用会发送一个几乎为空的 HTML 文件,在浏览器中构建页面;搜索引擎必须渲染它,而许多机器人从不渲染。Next.js 在服务器端渲染 React,因此 HTML 响应中已经包含标题、正文、链接和元数据。我们的 JavaScript SEO 指南解释了这一差异为何对索引至关重要。
在 App Router 中,组件默认是 Server Components。即使标记了 'use client' 的组件,也会在服务器端预渲染为 HTML。薄弱环节在于数据:凡是在 useEffect 中获取、或点击之后才加载的内容,都不会出现在初始 HTML 中。请在 Server Components 中获取内容,把客户端组件留给交互功能。
Next.js 允许按路由混用不同模式。这一选择会影响内容新鲜度、速度以及爬虫接收到的内容。
| 模式 | HTML 生成时机 | SEO 评价 | 适用场景 |
|---|---|---|---|
| 静态生成(SSG) | 构建时 | 最佳:完整 HTML,速度极快 | 落地页、文档、长青文章 |
| 增量静态再生成(ISR) | 构建时生成,之后在后台或按需刷新 | 大型或经常变化的网站的最佳选择 | 博客、产品目录、CMS 页面 |
| 服务器端渲染(SSR) | 每次请求时 | 良好:完整 HTML,取决于服务器速度 | 个性化或实时页面 |
| 客户端渲染(CSR) | 在浏览器中 | 较弱:大多数机器人看不到内容 | 需要登录的后台面板 |
Next.js 的 ISR 文档列出了它的优势:"无需重新构建整个网站"即可更新静态内容,并能处理大量页面而不必忍受漫长的构建时间。带有 export const revalidate = 3600 的路由最多每小时重新生成一次;如需精确控制,可在内容变化时调用 revalidatePath 或 revalidateTag。ISR 不支持静态导出(output: 'export')。对于必须保持客户端渲染的应用,我们的单页应用 SEO 指南介绍了替代方案。
提示
检查机器人实际收到的内容,而不是浏览器显示的内容:对 URL 运行 curl,或打开 view-source 搜索文章中的一句话。如果原始 HTML 中没有这句话,它就依赖 JavaScript。
在 App Router 中,Metadata API 取代了 next/head。根据 Next.js 元数据文档,你可以从 layout 或 page 导出一个静态 metadata 对象;当值取决于数据时,则导出 generateMetadata 函数,Next.js 会自动生成 head 标签。两者都只能在 Server Components 中使用。
export async function generateMetadata({ params }) {
const { slug } = await params
const post = await getPost(slug)
return {
title: post.title,
description: post.excerpt,
alternates: { canonical: `/blog/${slug}` },
openGraph: { images: [post.cover] },
}
}五条规则可以避免大多数问题:
在动态页面上,Next.js 会在首批字节之后以流式方式发送元数据,以加快渲染。文档说明,对于期望在 head 中读取元数据的机器人(通过 user agent 识别,示例包括 Bingbot、Twitterbot 和 Slackbot),流式传输会被禁用,并可通过 htmlLimitedBots 选项自定义名单。如果你关心的爬虫不在其中,请自行添加。在 Pages Router 中,对应的是 next/head 的 Head 组件,并用 key 属性避免重复标签。
两者都是 app 目录中的特殊文件。导出一个返回网址列表的函数的 sitemap.ts 文件会变成 /sitemap.xml;robots.ts 文件会变成 /robots.txt。sitemap 参考文档指出,该文件默认会被缓存,而 Google 的上限是每个站点地图 50,000 个网址;超过这个数量时,generateSitemaps 会把它拆分成多个文件。
import type { MetadataRoute } from 'next'
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const posts = await getPosts()
return posts.map((p) => ({
url: `https://example.com/blog/${p.slug}`,
lastModified: p.updatedAt,
}))
}只收录规范的、可索引且返回 200 的网址,并在 lastModified 中填写真实的更新日期。对于多语言网站,站点地图还支持 alternates.languages。在 robots.ts 中指向站点地图,并决定允许哪些 AI 机器人抓取网站;我们关于 AI 爬虫的 robots.txt 的文章列出了这些机器人。格式详情请见我们关于 XML 站点地图的词条。
| 问题 | 后果 | 解决方法 |
|---|---|---|
| 使用 onClick 和 router.push 导航 | Google 只跟踪带 href 的 a 元素 | 使用 next/link 的 Link 组件,它会输出真正的链接 |
| 不存在的内容以 200 页面返回 | Search Console 中出现"软 404" | 调用 notFound(),让路由返回 404 状态码 |
| 已迁移页面使用临时重定向 | redirect() 发送 307 | 使用 permanentRedirect() 或在 next.config 中设置 permanent: true(308) |
| 末尾斜杠混用 | 同一页面有两个网址 | 用 trailingSlash 选项统一格式,并保持规范链接一致 |
| 预览或测试环境被索引 | Google 中出现网站的重复副本 | 在非生产域名上发送 noindex |
| 标签页内容点击后才加载 | HTML 中缺少文字 | 在服务器端渲染全部内容,必要时用 CSS 隐藏 |
这些问题都会降低可抓取性:爬虫必须能通过链接发现每个网址,并获得干净的状态码。
Next.js 文档建议直接在页面或 layout 组件中,用类型为 application/ld+json 的 script 标签渲染 JSON-LD,数据来源与页面相同,并在序列化后的 JSON 中转义 < 字符以防止注入。由于它在服务器端渲染,Google 和 AI 爬虫都能在原始 HTML 中看到它。文章使用 Article(或 BlogPosting),根 layout 使用 Organization,深层页面使用 BreadcrumbList,电商页面使用 Product。Schema 生成器可以提供一个有效的起始代码块,然后用 Google 的富媒体搜索结果测试验证页面。
Next.js 自带的组件可以解决导致 Core Web Vitals 不佳的常见原因:
要衡量真实用户数据,而不只看实验室分数:我们的 PageSpeed Insights 指南介绍了如何解读两者。
Next.js 博客通常有三种形式:代码仓库中的 MDX 或 Markdown 文件(简单,但每篇文章都需要一次提交和部署)、在 Server Components 中查询的无头 CMS(Sanity、Contentful、Strapi、Payload),或从外部工具接收文章的发布 webhook。三种方式的 SEO 模式相同:一个动态路由 app/blog/[slug],配合 generateStaticParams、generateMetadata 和 ISR,用同一数据源生成站点地图,并有一个链接到所有文章的索引页。
webhook 让发布脱离部署流程。Route Handler 接收文章、保存,然后重新验证受影响的页面:
// app/api/publish/route.ts
import { revalidatePath } from 'next/cache'
export async function POST(request) {
if (request.headers.get('authorization') !== `Bearer ${process.env.PUBLISH_SECRET}`) {
return new Response('Unauthorized', { status: 401 })
}
const article = await request.json()
await savePost(article)
revalidatePath('/blog')
revalidatePath(`/blog/${article.slug}`)
return Response.json({ ok: true })
}注意
用密钥保护该接口,并重新验证准确的公开路径。ISR 文档提醒:在多个服务器实例且使用默认文件缓存时,按需重新验证只会清除接收请求的那个实例;请使用共享的缓存处理器。
服务器端渲染是 GEO(生成式引擎优化)的第一个前提。Vercel 于 2024 年 12 月发布的分析 The rise of the AI crawler 发现,"目前没有任何主要 AI 爬虫会渲染 JavaScript",点名了 GPTBot、ChatGPT-User、OAI-SearchBot、ClaudeBot 和 PerplexityBot,并统计到一个月内其网络上有 5.69 亿次 GPTBot 请求和 3.7 亿次 Claude 请求。预渲染了正文、标题和 JSON-LD 的 Next.js 页面对它们全部可读;客户端渲染的页面则不然。
第二个前提是值得引用的内容:每个章节回答一个问题,附带来源、数据和清晰定义,并定期发布。这正是我们的产品 Sorank 自动完成的部分。Sorank 是一款 autopilot 模式的 SEO 与 GEO 软件:它会找到你的关键词,其博客文章生成器每月撰写 20、60 或 120 篇文章,附带来源、内部链接和图片。在 Next.js 网站上,它通过安装页面所述的自定义 webhook 接入:你的 Route Handler 接收每篇文章、保存并重新验证博客。之后,AI 提及追踪每周检查 ChatGPT、Claude 和 Gemini 是否引用你的品牌。

一句话总结:预渲染每个希望被找到的页面,在服务器端定义元数据,并用与内容相同的数据源生成站点地图。Next.js 提供工具,排名和 AI 引用则取决于你用它发布的内容。如需持续为 Next.js 博客提供文章,请查看 Sorank 的方案,每月 49 美元起,可免费试用 3 天。
Next.js 基于 React 构建,因此比较的其实是渲染方式。默认的 React 单页应用在浏览器中渲染,发送的 HTML 几乎为空,而 Next.js 会在服务器端或构建时预渲染页面。爬虫,包括不执行 JavaScript 的 AI 机器人,无需额外配置就能从 Next.js 获取完整内容。
不会自动生成。在 App Router 中,你需要在 app 目录中添加一个返回网址列表的 sitemap.ts 文件,Next.js 会在 /sitemap.xml 提供它。对于大型网站,generateSitemaps 会把列表拆分成多个文件,因为 Google 每个站点地图最多接受 50,000 个网址。
两者都能获得良好排名,因为都会预渲染 HTML。新项目推荐使用 App Router:Server Components 减少了客户端 JavaScript,Metadata API、sitemap.ts 和 robots.ts 原生处理 SEO 文件。对于已经使用 Pages Router 的网站,仅为 SEO 而迁移通常不值得。
他们已先于您体验了 SORANK

