三年前,我接手了一个客户的博客——400篇文章,每月6万自然访问量,八年积累的PageRank——并将其迁移到闪亮的Next.js前端。六周内我们失去了34%的流量。不是因为新站点速度慢。不是因为内容消失了。而是因为我在四个具体问题上处理得很草率,我会在这篇文章中逐一讲解,这样你就不会重复我的错误。
Headless WordPress with Next.js 对性能和开发者体验来说确实出色。但如果你的规范标签错了、XML 站点地图指向旧域名、结构化数据在 WPGraphQL 和 getStaticProps 之间消失了,Google 才不在乎你的 Lighthouse 分数。迁移本身才是危险的部分。做对它主要取决于纪律,不是魔法。
---
为什么这次迁移首先会破坏 SEO
大多数教程都略过了一件事:WordPress 为你做了大量 SEO 工作,而你却没有意识到。Yoast 或 Rank Math 生成你的元标签。WordPress 核心处理你的永久链接结构。你的主题可能输出某种 schema 标记。你的 XML 站点地图每次发布时都会自动重新生成。
当你通过 WPGraphQL API 将内容层拉入 Next.js 并从新的前端服务时,所有这些基础设施都成了你的问题。每。一。个。
另一个问题是 URL 结构。大多数 WordPress 网站使用 /category/post-slug/ 或 /year/month/post-slug/ 或仅仅 /post-slug/。Next.js 给了你一个空白的路由画布。如果你规划得不仔细,那个空白画布就成了排名的墓地。
我经常看到的两种失败模式
首先是迁移URL的团队仍然会出现问题,通常是因为重定向应用不一致,或者新的sitemap在重定向生效前就上线了。其次是有意改变URL结构的团队(通常是为了清理),却把重定向映射当成事后补救。两者都可以修复。但都是不能接受的。
---
在触及任何东西之前先进行审计
在写第一行Next.js代码之前,你必须有一份完整的URL清单。我使用Screaming Frog爬取实时WordPress网站,导出每个可索引的URL,然后倾倒到电子表格中。对于400页的网站,这可能需要一小时的工作量。对于4000页的网站也只需一小时,因为这个工具是自动化的。
你要捕获的内容:
- 每个当前已索引的规范 URL
- 每个的 HTTP 状态(识别已存在的 404 和 301)
- 每个页面的元标题和描述
- 哪些页面具有结构化数据(使用富媒体搜索结果测试或直接查看源代码)
- 入站内部链接,这样你就知道哪些页面链向哪些页面
还要从Google Search Console拉取前50个页面,按点击次数排序。这些是你不能出错的页面。在电子表格中标记它们。像对待生产依赖一样对待它们。
Seahawk 在 2022 年末接手了一个电商客户——1,200 产品的 WooCommerce 店铺要迁移到无头架构。我们在写代码之前花了整整两天做审计。客户以为我们在浪费时间。结果我们救回了他们月均 9 万次自然会话。
---
将WordPress设置为真正的无头CMS
这部分基本上很直接。安装WPGraphQL并通过GraphQL API暴露你的内容。但有几件事值得认真考虑。
在WordPress端保持Yoast(或Rank Math)运行
尽管你不再将WordPress作为公共前端提供服务,也要保持SEO插件活跃。WPGraphQL for Yoast SEO(或等效的Rank Math扩展)通过GraphQL API直接公开所有SEO元数据、标题、描述、规范URL、OG数据、robots指令。这意味着你可以从Next.js查询它,并按照Yoast的意图精确渲染。
这是我之前提到的 2019 年流量下降事件的教训。我原以为可以在 Next.js 中从文章标题 + 网站名称重新生成标题。我们确实可以。但 Yoast 为大约 80 篇表现最好的文章手动自定义了 meta 标题,我们把所有这些都删除了。花了八周才恢复。
谨慎关闭 WordPress 前端
一旦你准备好将流量转向 Next.js,你不能让 WordPress 同时服务它自己的前端。大规模重复内容。最干净的方法是在 WordPress 安装上设置 robots.txt 为 Disallow: /,同时你的 Next.js 站点上线,然后最终防火墙 WordPress URL,使其只能在内部或通过 VPN 访问。
不要跳过 robots.txt 这一步。我见过团队在 CDN 级别阻止 WordPress,然后发现 Googlebot 有一个缓存路由。需要几个月时间才能清理干净。
---
完全复制 URL 结构
我的强烈默认建议:保持你的 URL 完全相同。相同的 slug,相同的永久链接结构,相同的末尾斜杠行为。Next.js 路由越接近 WordPress 路由,你需要的重定向就越少,你承担的风险就越小。
Next.js 动态路由让这很容易。如果你的 WordPress 文章放在 /blog/[slug],创建 pages/blog/[slug].js。完成。
麻烦的地方在于分类存档、作者页面、标签页面和分页存档(/blog/page/2/)。WordPress 会自动生成所有这些。在 Next.js 中你需要自己构建。很多团队会搁置这些,然后疑惑为什么爬虫覆盖率下降了。
这是我的 URL 对等检查清单(按编号):
- 单个文章/页面,完全匹配slug,包括任何子文件夹
- 分类存档,使用getStaticPaths从WPGraphQL拉取所有分类来重建/category/[slug]/
- 标签存档,同上,如果这些页面获得自然流量就不要跳过
- 检查作者存档,先看Search Console;如果点击数为零,可以用301重定向到首页
- 分页存档(/blog/page/[num]/)如果你有很多文章,值得保留
- 附件页面,几乎总是用301重定向到父文章;它们在WordPress中也是SEO的累赘
- Feed URL,/feed/应该301重定向到你的新RSS Feed(如果有的话),或者返回410(如果没有)
---
重定向:被所有人低估的部分
如果你要改任何URL——我会反对,但有时这是必要的——重定向映射必须在上线前构建好,并在暂存环境中测试
在Next.js中,重定向写在next.config.js里。小网站(少于200条重定向)没问题。更大的站点要么把它们放在JSON文件里导入,要么用中间件动态处理。Vercel的边缘中间件特别适合大型重定向表,因为它在页面渲染前运行,零延迟损耗
next.config.js 中的格式:
``redirects: [ { source: '/old-slug', destination: '/new-slug', permanent: true } ]``
permanent: true发送301。所有真正的URL变更都用它。不要用302(临时)除非你真的打算恢复,Google对两者的处理方式完全不同
在上线前测试每个重定向。我用一个简单的 bash 脚本遍历电子表格,用 curl 检查每个旧 URL 是否返回 301 状态码到正确的目标地址。写好脚本需要十分钟,能省去上线后数小时的崩溃。
---
Next.js 中的 Meta 标签、规范 URL 和结构化数据
大多数迁移在这里悄悄失分。内容在那里,URL 能用,但 SEO 信号错了。
Meta 标签
用next-seo。这是标准做法。把从WPGraphQL Yoast查询到的数据传给它。你的_app.js获取DefaultSeo配置,每个页面用NextSeo组件处理页面特定的覆盖。标题、描述、OG标题、OG图片、规范URL和robots指令直接从Yoast GraphQL响应拿,不要重新发明轮子
有一个容易被人忽略的东西:规范网址(canonical URL)。在WordPress中,Yoast会自动设置规范网址。在Next.js中你需要显式传入规范网址。如果你忘记了,Next.js会渲染出没有规范标签的页面,如果你的任何地方都有查询字符串(分页、筛选),你会比预期更快地遇到重复内容问题。
结构化数据
WordPress 主题和插件通常会自动输出 JSON-LD。在无头 CMS 中这些会消失。你需要重新构建它。对于文章,使用 Article schema。对于产品,使用 Product schema。对于本地商家,使用 LocalBusiness schema。我把这些写成接受 props 并返回 <script type="application/ld+json"> 标签的 React 组件。每个 schema 类型一个组件,在整个应用中重用。
在迁移前用富媒体搜索结果测试工具检查你之前有过的每个 schema 类型。记录下来。重新创建它们。在上线后用同一工具测试新的。
XML网站地图
不要用静态sitemap。动态生成它。小网站的话,在/sitemap.xml路由上用getServerSideProps。大型网站有数千篇文章,在构建时通过自定义脚本生成sitemap,输出到public/文件夹。Vercel每次部署都会运行这个,你的sitemap永远是最新的
在新网站上线的第一天将新的网站地图URL提交给Google Search Console。不是第三天。第一天。
---
上线后监控(90天窗口期)
迁移不是在上线时结束。它在你的排名稳定后才结束,根据Google文档,这可能需要几周到几个月,取决于爬虫预算和网站权威性
我每个工作日在第一个月要看的东西:
- Google Search Console → Coverage 报告,查找新的 404 或不应被排除的"Excluded"网址
- Search Console → Performance,按周比较你的前50个页面的点击量和展现量
- 用 Screaming Frog 重新爬取新网站,捕捉任何内部 404 或配置错误的规范标签
- Core Web Vitals,是的,Next.js网站应该更快,但要在现场数据(CrUX)中验证,而不仅仅是Lighthouse
如果你在前两到三周看到明显下降,不要立即惊慌。随着Google重新爬取和重新索引,几乎总会有短期波动。你要找的是第四周之后持续的下降。这才是表明结构出问题的信号。
回到2022年年底,这是一个不同于电商项目的项目,我们为一个SaaS博客启动了Next.js迁移,在第二周看到了20%的展现量下降。结果发现我们的动态生成的sitemap包含了noindex页面,因为我们没有正确过滤WPGraphQL查询。四小时内修复了。排名在三周内恢复了。监控在它复合之前就捕捉到了。
---
常见问题
WordPress迁移到Next.js需要多长时间?
说实话,这取决于网站复杂度而不是文章数量。一个100页的简洁URL宣传网站可以在两到三周内正确完成。一个有2000篇文章、自定义文章类型、ACF字段和WooCommerce集成的博客,如果你同时要做好SEO工作和开发,最少需要六到八周。别让任何人告诉你这是一个周末就能完成的活。
我应该在Next.js中使用Pages Router还是App Router?
截至2024年中期,我在新项目中默认使用App Router。但如果你的团队更熟悉Pages Router,而且这是一个时间紧张的迁移,就用你懂的东西。SEO影响微乎其微,两者都支持静态生成、服务端渲染和动态路由。next-seo包现在也支持App Router了。
我是否需要完全放弃WordPress主机?
不。WordPress可以留在现有的主机上,WP Engine、Kinsta、Cloudways,随便你用什么,只充当内容API。Next.js前端部署到Vercel或Netlify。两者通过HTTP通信。有些客户其实更喜欢这样,因为编辑团队可以继续用他们已经熟悉的WordPress管理后台。
那WordPress插件呢,比如在Redirection中管理的重定向,它们会影响SEO吗?
迁移前导出它们。Redirection插件有CSV导出功能。把所有现有的重定向导出来,加到next.config.js或边缘中间件中。不要假设它们会自动继承,不会的,因为它们存在WordPress数据库中,而Next.js根本不知道它们存在。
不管怎样我的谷歌排名都会下降吗?
几乎总是会有一些短期波动。一次执行得当的迁移,零URL变化,适当的重定向(必要时),复制的元数据和结构化数据,以及重新提交的sitemap,应该在四到六周内稳定下来。我见过持续数月的下降,都是由特定的技术错误造成的,而不是迁移本身。
---
迁移本身不是难点。难点是有纪律地完成每一个枯燥无趣的步骤,审计、重定向映射、schema重建,然后才写任何聪明的Next.js代码。把顺序搞对,你会得到一个更快的前端,以及你开始时相同的排名。一旦Core Web Vitals的改进生效,可能会更好。
