
Next.js 13 的 App Router 不再支持传统的 _document.tsx,而是通过 app/layout.tsx(根布局)统一接管 HTML 文档结构的定制,包括 <html>、<head> 和 <body> 的控制。
next.js 13 的 app router 不再支持传统的 `_document.tsx`,而是通过 `app/layout.tsx`(根布局)统一接管 html 文档结构的定制,包括 ``、`
` 和 `` 的控制。在 Next.js 13 引入 App Router 后,原有的 Pages Router 中用于深度定制服务端返回 HTML 的 _document.tsx(或 _document.js)已完全弃用,且不被 App Router 支持。取而代之的是一个强制性的、位于 app/ 目录顶层的 根布局组件(Root Layout),即 app/layout.tsx —— 它不仅是页面共享布局的入口,更是整个应用 HTML 文档结构的唯一可控起点。
✅ 正确做法:使用 app/layout.tsx 替代 _document
该文件必须导出默认函数组件,并接收 children 属性(代表当前路由渲染的内容)。你可以在此自由定义 <html> 标签属性、注入全局 <head> 内容(如字体、meta、样式链接),以及包裹 <body> 结构:
// app/layout.tsx
import type { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="zh-CN" className="scroll-smooth">
<head>
{/* 自定义 meta 标签 */}
<meta name="description" content="基于 Next.js 13 构建的现代化前端应用" />
{/* 加载设计系统 CSS(如你的定制 Design System 包) */}
<link rel="stylesheet" href="/css/design-system.css" />
</head>
<body className="min-h-screen bg-gray-50">
{/* 可在此插入全局 Provider,例如 ThemeProvider、StyleProvider 等 */}
<div className="container mx-auto px-4 py-6">
{children}
</div>
</body>
</html>
);
}⚠️ 注意事项:
- app/layout.tsx 是 必需文件(Required),缺失将导致构建失败;
- 它仅在服务端渲染(SSR)时生效,可安全操作 document 无关的 DOM 结构(如 <html> 属性);
- 若需动态 <head> 控制(如页面级 title、SEO meta),应配合 next/head 的替代方案 —— 推荐使用内置的 metadata 或 generateMetadata 函数在对应 page.tsx 中声明;
- 不支持直接操作浏览器 document 对象(如 document.documentElement.setAttribute),所有 HTML 结构变更必须通过 JSX 声明式完成;
- 如使用 JavaScript 而非 TypeScript,请命名为 app/layout.js,类型定义自动省略。
? 总结
| 场景 | Pages Router | App Router |
|---|---|---|
| 自定义 <html>/<head> | _document.tsx | app/layout.tsx(根布局) |
| 全局样式/脚本注入 | ✅ 支持 | ✅ 支持(通过 <head> 或 <body> 子节点) |
| 运行时机 | 服务端(仅) | 服务端(SSR/SSG),不参与客户端 hydration |
因此,若你正在集成自研或第三方设计系统(如要求注入全局 CSS、设置字体族、添加无障碍属性等),只需在 app/layout.tsx 中统一配置即可,无需寻找已不存在的 _document —— 这是 App Router 更简洁、更符合 React Server Components 设计范式的演进结果。









