JavaScript SEO:确保链接在渲染后依然有效
Google 使用最新的 Chromium 引擎渲染 JavaScript。问题通常不在于渲染本身,而是链接未能变成锚点,或者页面依赖于爬虫不具备的状态。
ArchiLinks 研究团队 ·

爬虫看到的内容
自 2019 年 5 月起,Googlebot 一直使用最新的 Chromium 引擎。这已经解决了它能否运行现代 JavaScript 的问题。
实际风险来自更古老的问题:渲染发生在抓取之后且可能延迟,点击或登录后才能看到的内容不会出现,以及由 div 上的 onclick 处理程序生成的链接不是真正的链接。在你检查最近迁移到 React 前端网站页面上的反向链接之前,请确认这些页面在原始响应或渲染后的 HTML 中显示其内容。
SSR、SSG、CSR:对链接的影响
| 方法 | 首次响应中的内容 | 作为锚点的内部链接 | 适用场景 |
|---|---|---|---|
| SSR(Next.js、Nuxt) | 是 | 是,如果你使用真正的锚点 | 数据不断变化的公开页面 |
| SSG 或预渲染 | 是 | 是 | 文档、博客、营销页面 |
| CSR 单页应用 | 否,空壳 | 仅在渲染后 | 登录后的仪表板 |
| 混合模式(SSR 首页,CSR 应用) | 按路由 | 按路由 | 大多数具有公开侧的产品 |
测试一:原始 HTML 与渲染后的 HTML
如果关键链接出现在首次响应中,问题即告解决。如果没有,请与无头渲染结果进行比较。
# raw response: are the links there?
curl -s https://new-shop.com/guides/ | grep -o '<a [^>]*href="[^"]*"' | head -20
# rendered DOM with headless Chrome
chrome --headless --dump-dom https://new-shop.com/guides/ | grep -c '<a '
外部链接的来源
渲染错误会隐藏你的内容,但不会抹去其他站点已经给你的链接。
迁移到 Next.js、Vite 或无头 CMS 后,对主机运行 toppages 并测试链接最多的 20 个 URL 的状态、规范链接和可见内容。先做这一步。如果一个拥有 40 个链接域名的页面返回空壳或客户端 404,请优先修复它,因为你的权重就在那里流失。内部与外部权益页面 展示了如何将此列表与内部链接进行比较,迁移检查清单 将测试纳入发布计划中。
框架的重要性不及纪律。使用模板引擎的 Express、WordPress 主题和 Next.js 应用路由器都可以提供可爬取的链接。如果团队交付的锚点仅在点击后才存在,它们也都会失败。
链接与渲染检查清单
- 导航和分页使用
<a href>,而不是在其他元素上使用点击处理程序。 - 每个路由返回真实的状态码。软 404 页面必须返回 404。
- 由 JavaScript 注入的
noindex或规范链接必须与服务器响应中的一致。 - 首次响应中的备用内容是真正的页面,而不是 Google 可能会索引的加载动画。
- 认证代码不会在公开路由上重定向爬虫。
- 渲染所需的 CSS 和 JS 文件未在 robots.txt 中被阻止。
- 懒加载使用 IntersectionObserver 或原生加载属性,而不是滚动事件。
解读搜索控制台证据
如果你询问正确的报告,搜索控制台可以回答大多数渲染问题。使用 URL 检查,然后查看抓取后的页面。
比较三件事:Google 抓取的 HTML、截图以及未能加载的页面资源。在你的浏览器中看起来完整但在截图中为空的页面,通常是由于脚本错误或被阻止的资源,修复方法在于你的构建过程,而不是内容。
记住延迟。你今天发布的变化只有在 Google 重新抓取 URL 后才会出现在检查工具中,这可能需要几天时间。
何时值得使用 SSR
必须排名的公开页面:是。仪表板:否。
如果某个路由应吸引有机流量,请在首次响应中提供内容。如果它位于登录之后,请跳过复杂性。按路由选择而非按项目选择,并记录决策,以便下一位开发人员不会将其撤销。
- 使用富媒体结果测试和 URL 检查来比较渲染输出。
- 每次框架升级后,使用搜索控制台的实时测试进行测试。

是否需要服务器渲染,还是预渲染就足够了?
服务器渲染是可选的。它是一种让首次响应携带爬虫所需内容的方式。许多公开站点通过预渲染、静态构建或对重要页面进行服务器渲染来实现这一点,而让登录部分保持原样。
假设你的产品页面和文档是公开的,而仪表板位于登录之后。预渲染第一组。让仪表板在客户端运行。这样,公开页面在首次响应中携带其链接,而仪表板可以保持其所需的复杂性。
仅预渲染首页
预渲染首页解决了第一次抓取,但会让其他所有路由等待浏览器。如果首页链接到客户端渲染的分类页面,这些页面上的链接仍然依赖于渲染。检查你拥有的每个模板,而不仅仅是入口。
保留一个简短的公开路由列表及其渲染方法。该列表将比抓取报告更快地显示差距。
服务器渲染是否会影响本地可见性
服务器渲染可以改变首次内容出现的速度,读者能感受到这一点。它本身并不能使页面与本地查询相关。这些信号来自页面内容、业务详情和指向它的链接。
将渲染视为这些信号被爬虫读取的方式,并使用 API 单独测量链接。
提供单个壳的 Vite 和 React 应用
为每个路径提供一个 HTML 壳的 Vite 构建将所有工作放在客户端。此类应用仍可能针对某些查询排名,但每个公开路由都需要一个计划:预渲染它、在服务器上渲染它,或者接受损失并记录下来。
在重新构建后检查网站路由的反向链接之前,决定每个公开路由如何获取其内容。否则,链接数据将显示外部链接落在空页面上。
测试路由是否显示其链接
两个测试可以回答大多数问题。原始响应显示脚本运行前爬虫获得的内容。渲染后的 DOM 显示浏览器随后构建的内容。仅在第二个中出现的链接仍然是链接,但它依赖于渲染顺利进行。
解读搜索控制台中的实时测试
从 URL 检查对每个路由单独运行实时测试。查看渲染后的 HTML,然后查看未能加载的资源列表。被阻止的脚本可能会删除整个导航块,而页面看起来很单薄,但没有显示任何可见错误。
框架升级后重复测试,因为新默认值可能会改变链接是在脚本运行之前还是之后渲染。未索引页面 指南涵盖了当渲染后的页面仍然未被索引时该怎么做。
当路由渲染但内容是加载动画时
首次响应中的备用内容比大多数团队预期的更重要。加载动画或空容器意味着页面在该时刻没有为爬虫携带任何文本。将标题、简介和主要链接放入首次响应中,即使详细列表稍后加载。
作为真正页面的备用内容可以保持简单。它的唯一任务是在其余内容到达之前保留内容。
迁移客户端站点而不丢失其链接
列出带有外部链接的路由
对主机运行 toppages 并记录前 50 个 URL。首先测试这些路由,在代码更改之前,以便你知道重建必须保留什么。
比较原始和渲染后的输出
对于每个路由,检查旧版本和新版本中的原始 HTML 和渲染后的 DOM。注意任何仅存在于其中一个版本中的链接。
用锚点替换点击处理程序
使用正确的地址将导航转换为真正的锚点。速度工作可以等待一个冲刺,而缺少锚点会使路由失去进入站点的路径。
发布后重复测试
发布一周后,对相同的路由运行实时测试,并将结果与之前的结果进行比较。差异显示重建在何处改变了输出。
客户端应用中的状态码和重定向
单页应用通常在不找到页面时显示屏幕,而服务器返回状态 200。Google 可能会将此类页面视为软 404,指向缺失 URL 的外部链接对你几乎没有帮助。修复方法属于服务器端。
仍然返回 200 的未知路由
对于任何不存在的路由,从服务器返回真实的 404,并为通过客户端路由到达的访客保留应用内的未找到屏幕。如果存在替代方案,请发送 301。
每次发布后在实时主机上检查几个虚构的地址。要读取的是响应代码,而不是你在浏览器中看到的页面。
在浏览器中运行的重定向
页面加载后触发的重定向(例如,通过组件内读取 URL 参数)与服务器重定向不同。爬虫可能会在重定向运行之前索引首次响应。如果路由已永久移动,请从服务器返回 301 并保留更改内容的参数。重定向映射配方 展示了如何测试这些规则。