next export 出来的文章页 DOM 里只有一个空 div,正文全在 __NEXT_DATA__ 的 JSON 里,GSC 抓到的页面被判无正文。

一开始怀疑是「静态导出不执行客户端 hydration,HTML 保持初始状态」,查了一圈,方向不对。

这类报错背后常见的原因有几处,逐个排除就行。getServerSideProps 在静态导出时退化,数据只进页面 props。也可能是组件用 useEffect 挂载后才渲染列表,导出时 DOM 是空的。

少数情况下是没有配置 fallback,动态路由全部走客户端。

上来先检查导出文件里有没有正文

grep -c '文章正文' out/post/1/index.html

再往下确认是否用了静态路径生成

grep -rn 'getStaticPaths' pages/ | head

接着把数据渲染从 useEffect 挪到渲染阶段

sed -i 's#useEffect(() => setData(d), [])#const [data] = useState(initialData)#' pages/post.js

剩下的就是重新导出并复核

npm run build && npx next export && grep -o '<h1>[^<]*</h1>' out/post/1/index.html

当时还开着另一个排查窗口,两边日志对照着看才定位到。

恢复的判定其实很直接。导出的 HTML 里能直接用 grep 找到正文首段,GSC 抓取的原始 HTML 与页面显示内容一致。

静态导出只保证 HTML 存在,不保证内容在 HTML 里,数据放 props 还是放 DOM 是两回事。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189