首页 AdSense 广告显示正常。点进文章——空白广告位。一样的 ad unit ID、一样的域名、一样的通过审核的 AdSense 账号。这是”不同模板”故障模式,绝大多数不是 AdSense 的 bug。是两个模板之间有某个结构性差异:一条 CSS 规则、漏装的 script 标签、文章视图把布局塌成 0、或者单篇文章触发了首页不触发的内容稀薄判定。
诊断关键是用 DevTools 把两个模板放一起对比,不是反复看 AdSense 设置。
常见原因
按命中率从高到低。
1. AdSense 脚本只在首页加载、文章模板没装
常见场景:你把 AdSense 脚本加到首页 layout,但文章用另一个 layout,没包含它。文章的 <ins> 标签在那里,但脚本从来没执行过。
怎么判断:文章页 DevTools Network → 过滤 adsbygoogle.js。0 个结果就是脚本没加载。
2. 文章模板把 slot 包在塌掉的 CSS 容器里
slot 在 DOM 里但父容器是 display: none、width: 0、height: 0、或者在没展开的 tab/accordion 里。首页用的是另一种父结构,slot 在那边正常。
怎么判断:文章页选中 <ins class="adsbygoogle"> → Computed → 看 width 和 height。0 就是父容器塌了。跟首页版本对比。
3. ad unit ID 不同——只有首页的配对
两个模板用了不同的 data-ad-slot 值。首页那个在 AdSense 里配好了;文章那个指向一个被删除的或从未创建的 slot。
怎么判断:
grep -rn "data-ad-slot" src/
把值跟 AdSense → Ads → By ad unit 对比。文章里的必须对应一个已批准的 unit。
4. 文章内容太薄无法承载广告
AdSense 有内容政策限制小内容页面的投放。首页通常是聚合内容(最新文章、hero 文字、分类)。某些很短的文章页单独评估时可能不到阈值。
怎么判断:字数不到 300 + 图片/结构很少 = 大概率太薄。AdSense 会给单篇 data-ad-status="unfilled",但首页正常投放。
5. 文章模板在 slot 渲染后才懒加载 AdSense
如果框架异步 hydrate 文章页,AdSense 脚本在 <ins> 已经进入 DOM 之后才加载,但从来没 push 过来,slot 就一直空。
怎么判断:控制台 window.adsbygoogle?.loaded。文章页是 undefined 说明 push() 没跑。首页正常就说明那个模板 push() 时机对。
6. CSP / iframe sandbox 把文章模板的广告挡了
文章模板用了更严的 CSP 或者把内容包在 <iframe sandbox> 里,AdSense 无法渲染。
怎么判断:文章页 DevTools 控制台。看有没有 “Refused to load” 或 “iframe sandbox” 错误提到 googlesyndication。
最短修复路径
第 1 步:验证两页都加载了脚本
// 在每页的 DevTools 控制台
document.querySelectorAll('script[src*="adsbygoogle"]').length
// 两页都应该是 1
文章页是 0 就是模板没装。挪到共享 layout。
第 2 步:对比 <ins> 的计算尺寸
// 每页都跑一次
Array.from(document.querySelectorAll('ins.adsbygoogle'))
.map(el => ({ status: el.getAttribute('data-ad-status'), w: el.offsetWidth, h: el.offsetHeight }));
| 首页 | 文章 | 诊断 |
|---|---|---|
filled,w/h > 0 | unfilled,w/h = 0 | 文章 CSS 把 slot 塌了 |
filled,w/h > 0 | undefined,w/h > 0 | 文章模板里 push() 没跑 |
filled,w/h > 0 | unfilled,w/h > 0 | 内容薄或 ad unit ID 不同 |
第 3 步:确认文章模板里 AdSense push() 真的跑了
文章模板里 script 标签必须存在且 push() 必须执行。SSR 框架:
<ins class="adsbygoogle" ...></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
SPA 路由切换(Next、Astro view-transitions 等):每次切路由重新跑 push()。
第 4 步:验证 ad unit ID 对得上
grep -rn "data-ad-slot" src/ | sort -u
打开 AdSense → Ads → By ad unit。每个 grep 结果都应对应一个活跃 slot。
第 5 步:测一篇不同的文章
如果只有一篇有问题、其它正常,就是那篇太薄(原因 #4)。加 500 字以上有分量的内容。
所有文章都有问题就是模板级(原因 #1、#2、#3、#5)。
第 6 步:跑 Ad Inspector
装 Google 的 Ad Inspector Chrome 扩展。打开文章。Inspector 会显示 “no ad served because [reason]“,原因文案通常直接点出问题。
哪些情况可能不是你操作错了
AdSense 填充率一天内波动 10-30%。健康页偶尔空也是常态。诊断阈值是”连续几小时刷新都空白”,不是”刷一次空”。
容易误判的情况
“文章页广告不出来”经常被当成 AdSense 的 bug。绝大多数是那个模板特有的模板 / 结构 / 内容问题。
预防建议
- 跨模板用同一个
<AdSlot>组件,不要复制粘贴<ins>标签。 - AdSense 脚本只在一个根 layout 里加载,所有页面共享。
- CI 里校验广告容器 CSS 尺寸:每个
<ins>父容器宽度必须非 0。 - 想变现的文章设最低字数(~500 字)。
- 框架升级或路由改动后,至少在 3 个文章 URL 上重新验证广告投放。
FAQ
- 填充率为什么波动? 广告主需求随内容 / 受众 / 地区 / 季节波动——10-30% 是正常的。
- 加更多广告能提升填充吗? 到一定程度。过多稀释每个 slot。大多数细分领域,每篇 2-3 个广告位是甜点。