Next.js 13 App目录SSR失效求助:页面Body为空仅含脚本
核心排查逻辑
App目录默认以服务端组件为基础,出现Body为空的情况,大概率是整个应用的渲染逻辑被客户端组件完全劫持,或者配置/路由设置导致服务端渲染(SSR)失效。
具体解决步骤
确保根Layout是服务端组件:根
app/layout.tsx绝对不能加'use client'指令。它是整个页面的骨架,必须由服务端直接渲染输出到HTML中。一旦标记为客户端组件,整个页面都会转为客户端 hydration 模式,初始HTML只会包含渲染脚本,不会有实际内容。正确的根Layout示例:
export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="zh-CN"> <body> <p>这是服务端直接渲染的内容</p> {children} </body> </html> ); }检查页面组件的客户端标记:
app/page.tsx及子路由的page.tsx默认是服务端组件,除非有交互需求(比如点击、表单),否则不要加'use client'。如果所有页面都被标记为客户端组件,初始HTML自然不会有渲染好的内容。核对
next.config.js配置:避免错误开启强制静态导出或客户端渲染的配置,比如误设output: 'export'却没执行完整的静态导出流程;如果需要SSR,保持默认配置即可。若用静态导出,必须执行next build && next export,确保所有页面都能生成静态HTML。验证生产环境的实际效果:开发环境为了热更新会有特殊处理,可能出现Body临时为空的假象。建议构建生产版本(
npm run build && npm start)后再查看HTML源码,生产环境的渲染结果才是最终上线的状态。限制全局客户端组件的范围:如果有全局状态管理、UI库Provider这类客户端组件,只在需要交互的页面或局部组件中引入,不要包裹整个根Layout或所有页面。比如把状态Provider放在具体的客户端页面内部,而非根Layout里。
关键原理
Next.js 13 App目录的SSR机制是:服务端组件直接在服务器生成HTML字符串发送给客户端;客户端组件则先在服务器生成 hydration 所需的JSON和脚本,等客户端加载完成后再渲染。如果整个应用的入口(根Layout+页面)全是客户端组件,初始HTML就只会有客户端渲染的资源,没有实际页面内容,自然会影响SEO。
内容的提问来源于stack exchange,提问作者Yoann Buzenet

