内链没被 Google 发现:先排除 GSC 报告 Bug,再修 JS 渲染

页面有 50 个内链,Search Console 却显示 0——先排除 2026 年 5-6 月的 GSC 报告故障,再处理 JS 渲染、nofollow 和伪链接。给出诊断表、修复路径和验证方法。

你网页上明明有 50 个内链指向各种文章,但 Search Console → Links → Internal links → Top linked pages 里某些 URL 却显示 “0 internal links”。或者 URL Inspection 工具显示 “Discovered – currently not indexed”,可你明明已经从五个页面链过去了。

最快的判断: 在改任何代码之前,先排除两件事。(1) 在 2026 年 5 月 21 日到 6 月 12 日之间,Search Console 的 Links 报告本身坏了——大量站点一夜之间看到链接归零或暴跌 87%-90%,而期间那次”修复”也只是把数字回滚到了旧数据。如果你的暴跌是最近、且全站性的,那可能是报告的问题,不是你内链的问题。(2) 这个报告是抽样,不是完整索引,而且会延迟好几天,所以单个 URL 显示 “0” 也可能是正常的。如果归零持续了好几周、且只针对特定页面,那基本就是下面这个真问题:Googlebot 看不到那些链接。它第一遍抓取不会执行每个脚本,不会点击,也不会展开折叠面板。你浏览器里看得见的链接,在 Google 抓到的 HTML 里可能根本不存在。

先排除报告本身的问题

Links 报告不是实时的、也不是穷尽式的计数:

  • 它是抽样。 Google 官方文档明说它 “isn’t a comprehensive list of every link on your site… It shows a sample of internal and external links”(不是全站链接的完整清单,只是内外链的一个样本)。一个流量高的页面,确实可能有 Google 跟过、但报告里从来没出现的链接。
  • 它有延迟。 链接数据比抓取晚好几天,而且和排名系统是分开的。你昨天才链过去的页面,今天不会显示出来。
  • 它在 2026 年坏过。 Links 报告在 2026 年 5 月 21 日停止更新新数据。大约 5 月 23 日 Google 把它回滚到了约一周前的旧数字(看起来像修好了,其实显示的是陈旧计数),直到 2026 年 6 月 12 日才真正恢复新鲜数据。如果你的 “0 links” 或突然崩塌正好对上这个时间窗,先等新数据回来,别急着动代码。

哪怕报告少算了,Google 在算法层面也可能仍在使用这些链接——报告是个诊断工具,不是排名信号本身。要确认某条具体链接,用 URL Inspection(见下文),而不是去信那个汇总数字。

你属于哪一类?

症状可能原因怎么确认
2026 年 5 月底前后全站崩塌GSC 报告 Bug(现已修复)对一下日期;6 月 12 日后重查
特定页面显示 0;链接要交互后才出现JS 渲染的链接curl 静态 HTML 与浏览器计数对比
链接在折叠面板 / Tab 切换里隐藏链接被打折搜模板里的 display: none<details>、隐藏的 tabpanel
源码里链接很多但计数很低不小心加了 rel="nofollow"grep 渲染后 HTML 里的 nofollow
卡片/按钮能跳转但不计数不是真正的 <a href>(onclick / data-link看源码,找带 JS 跳转的 <button>/<div>
目标页根本没被抓目标被 robots.txt 屏蔽查 robots.txt + URL Inspection 覆盖情况

常见原因

1. 内链在 hydration 之后才渲染

React / Vue / Svelte 的 client-side rendered 链接,初始 HTML 里没有,全靠 JS 把组件挂载上去后才出现。

Google 确实会渲染 JS,但分两波。Googlebot 先索引原始 HTML,然后把页面排进 Web Rendering Service (WRS) 队列,由无头 Chromium 稍后执行 JS。截至 2026 年 6 月:

  • 渲染的中位延迟约 5 秒,但中位数掩盖了一条很长的尾巴。Onely 的测试发现,提交两周后,仍有 5%-50% 依赖 JS 的新页面没被索引
  • WRS 不会无限等待异步任务(比如要等 useEffect 里 fetch 完才渲染的列表)。
  • 在抓取预算紧张或渲染队列拥堵时,第二波可能滞后数天到数周,所以只靠 JS 渲染的链接会被很慢地发现、甚至发现不了。

如何判断:

# Google 第一遍看到的 = curl 拿到的静态 HTML
curl -sL https://yourdomain.com/page | grep -c "href=\"/article-"
# 和你浏览器里看到的数量对比(DevTools → Elements → Cmd+F 搜 "href=")

或者用 Search Console → URL Inspection → “Test live URL” → “View tested page” → “HTML”,搜你的链接。如果抓取的 HTML 里找不到,说明被 JS 隐藏了。

2. 链接在折叠面板 / 抽屉 / Tab 切换里

哪怕 HTML 是静态生成的,藏在 display: none、默认折叠的 <details> 或默认不显示的 Tab 面板里的链接,都会被打折。爬虫能读到 HTML,但 Google 一直表示对隐藏内容的权重低于可见内容,而你用来做发现的链接,不该需要先点一下才出现。

如何判断: 搜你模板里的 display: nonehidden<details>tabpanel hidden 等。

3. 不小心加了 nofollow

<a href="/article" rel="nofollow">链接</a>

从 2020 年起,Google 把 rel="nofollow" 当作提示 (hint) 而非硬性指令,所以它可能仍然会抓目标页——但不保证,而且被 nofollow 的内链会浪费你本可以传给自己页面的内部 PageRank。内链永远不该加 nofollow。常见的误加来源:

  • WYSIWYG 编辑器默认加 nofollow(很多 CMS 都这样)
  • 用户生成内容 (UGC) 模块对整块内容自动加 nofollow
  • 把外链模板复制过来用到了内链上

如何判断:

curl -sL https://yourdomain.com/page | grep -E 'nofollow|sponsored|ugc'
# 有输出 = 存在这些属性;再看是加在哪些链接上

4. 链接是 button / 卡片 + JS 跳转

<button onclick="location.href='/article'">查看文章</button>
<div data-link="/article" class="card"></div>

这些都不是 <a href> 元素。Google 已确认它只跟 <a> 标签里真正的 href 链接——onclickdata-link、纯路由跳转都不算可发现的链接。

5. 链接放在 noscript 或 iframe 里

<noscript> 里的内容 Google 一般忽略;<iframe> 里的链接属于被框入的那个文档,不会把发现性或权重传给主页面。

6. 目标 URL 在 robots.txt 被屏蔽

链接本身可见,但目标 URL 在 robots.txt 里被 Disallow,Google 就不会去抓。这时对目标页做 URL Inspection 会显示 “Blocked by robots.txt”。

最短修复路径

Step 1:看在 disabled-JS 下你的内链还在不在

# 抓静态 HTML 响应(也就是第一遍抓取看到的)
curl -sL https://yourdomain.com/your-page > raw.html

# 数 <a href> 链接
grep -oE '<a [^>]*href="[^"]+"' raw.html | wc -l

# 与浏览器里的数量对比(DevTools → Elements → Cmd+F 搜 "href=")

差值大 = 大多数链接靠 JS 渲染,发现不可靠。

Step 2:把关键内链改成 SSR / SSG

用 Next.js 时,把链接放到服务端渲染,不要放在客户端 useEffect 里:

// 错:useEffect 里 fetch 后才渲染 —— 链接只在 hydration 之后才存在
function Related() {
  const [items, setItems] = useState([]);
  useEffect(() => { fetch('/api/related').then(r => r.json()).then(setItems); }, []);
  return items.map(i => <a href={i.url}>{i.title}</a>);
}

// 对:用 getStaticProps / getServerSideProps —— 链接进了 HTML 响应
export async function getStaticProps() {
  const items = await getRelated();
  return { props: { items } };
}
function Related({ items }) {
  return items.map(i => <a href={i.url}>{i.title}</a>);
}

用 App Router 时,让组件保持 Server Component(别加 "use client"),标记才会随 HTML 一起发出。Astro 默认就是 SSG,没这个问题;Vue 用 Nuxt 的 useAsyncData;Svelte 用 SvelteKit 的 load

Step 3:把折叠 / Tab 里的关键链接展开

把”相关文章”模块从 <details> 改成默认展开的 <section>,Tab 切换里的核心导航也一样。如果设计上必须折叠,至少在 HTML 里输出全部链接、用 CSS 控制可见性,不要”折叠时 DOM 里都没有”。

Step 4:审查 rel=“nofollow”

# 全站扫源码里的 nofollow
rg 'rel="[^"]*nofollow' src/

内链不应该带 nofollow;把 nofollow(或 sponsored / ugc)只留给真正该用的链接。从源头修:别让 CMS 的 WYSIWYG 默认加 nofollow;UGC 的 nofollow 只作用在用户提交的内容上,不要连模板自带的相关链接也包进去。

Step 5:所有可点击元素改成 <a href>

<!-- 错 -->
<button onclick="location.href='/article'">查看</button>
<div data-link="/article" class="card">...</div>

<!-- 对 -->
<a href="/article" class="button">查看</a>
<a href="/article" class="card">...</a>

如果需要按钮的样式,把 <a> 做成按钮的样子就行——保留真正的 href

Step 6:用 Search Console URL Inspection 验证

修完后:Search Console → URL Inspection → 输入页面 URL → “Test live URL” → “View tested page” → “HTML”,Cmd+F 搜你的目标内链。如果在抓取的 HTML 里,说明 Google 看得到了。然后在目标页上点 “Request indexing” 催一次重新抓取。

怎么确认修好了

  1. 抓取的 HTML 里有这条链接(URL Inspection 实时测试)——这是最确定的检查,而且马上就能看。
  2. 目标页的覆盖状态在变:从 “Discovered – currently not indexed” 往 “Crawled” 再到 “Indexed” 走。
  3. Internal links → Top linked pages 的计数上升。 这是最慢的信号:它是延迟的抽样,留 1-2 周(如果赶上像 2026 年 5-6 月那样的报告故障,还要更久)。如果第 1、2 项已经通过,别因为这里还显示 0 就以为修复失败了。

预防建议

  • 关键内链永远 SSR / SSG,绝不只靠客户端 fetch 才出现。
  • 用真正的 <a href>,杜绝 onclick / data-link 这类伪链接。
  • CI 加 no-JS 抽测:curl 静态 HTML,断言关键内链数 >= N
  • nofollow 只用在 sponsored 外链 / UGC,模板里默认不加。
  • 折叠 / Tab 设计先过 SEO 评审:核心导航能不能默认展开。

常见问题

Search Console 突然全站显示 0 内链,是我把什么弄坏了吗? 如果发生在 2026 年 5 月底,多半不是你的问题。Links 报告在 2026 年 5 月 21 日坏掉,直到 6 月 12 日才恢复新数据。改代码前先看你的暴跌是否对上这个时间窗。如果不在这个窗口里,全站归零就比较反常,值得查。

Google 真的不渲染 JavaScript 吗? 它渲染,但通过 WRS 分成延迟的第二波。中位延迟约 5 秒,但有相当一条尾巴要等数天到数周,而且提交两周后仍有 5%-50% 依赖 JS 的页面没被索引。对于你用来做发现的链接,把它们放进服务端 HTML 里。

nofollow 的内链是不是完全被忽略? 从 2020 年起 nofollow 是提示,所以 Google 可能仍会抓目标页——但不保证,而且你白白浪费了本可以传出去的内部权重。永远别给自己的内链加 nofollow。

为什么 Search Console 里的计数比我实际的链接数少? Links 报告明确是抽样,不是完整清单,而且延迟好几天。数字偏低不代表 Google 漏掉了链接;要确认具体某条,用 URL Inspection。

我的链接是真正的 <a href>、也是服务端渲染的,但目标页还是 “Discovered – currently not indexed”,为什么? 发现这一步成功了,索引是另一个独立决策。这个状态通常是抓取预算或质量原因,不是链接问题。从已被索引的页面加强对它的内链,并对目标页 Request indexing。

Internal links 报告多久才会反映我的修复? 一般 1-2 周,因为它是延迟的抽样。别靠它来验证修复——用 URL Inspection 抓取的 HTML,那个是实时更新的。

相关阅读

外部参考:Google: Links reportGoogle: Fix Search-related JavaScript problemsGoogle: Qualify outbound links(nofollow / sponsored / ugc)

标签: #SEO #Google #Search Console #收录