Next.js 自定义 Document 全面指南
2025-07-05 01:39:18作者:幸俭卉
什么是自定义 Document?
在 Next.js 项目中,_document
文件是一个特殊的服务器端渲染组件,它允许开发者自定义整个应用的 HTML 文档结构。与常规页面组件不同,_document
只在服务器端执行,用于控制 <html>
和 <body>
标签等基础文档结构。
为什么需要自定义 Document?
默认情况下,Next.js 会自动生成一个基本的 HTML 文档结构。但在以下场景中,你可能需要自定义 _document
:
- 需要为所有页面设置统一的 HTML 属性(如 lang 属性)
- 需要在文档头部添加全局的 meta 标签或脚本
- 需要使用 CSS-in-JS 库并需要服务器端渲染支持
- 需要在文档中添加自定义的全局内容
基础实现方式
创建一个自定义 Document
非常简单,只需在 pages
目录下创建 _document.tsx
或 _document.jsx
文件:
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="zh-CN">
<Head>
{/* 这里可以添加全局的 head 元素 */}
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
关键组件说明
<Html>
: 包裹整个文档的根元素,可以设置 lang 等属性<Head>
: 用于放置文档头部元素(不同于next/head
)<Main>
: Next.js 页面内容的渲染位置<NextScript>
: Next.js 所需脚本的注入位置
重要注意事项
-
客户端限制:
_document
仅在服务器端渲染,不能使用任何客户端特性如 onClick 等事件处理器 -
Head 组件区别:
_document
中的<Head>
不同于next/head
,前者用于全局 head 内容,后者用于页面级 head 内容 -
组件限制:
<Main />
之外的 React 组件不会被浏览器初始化,不应在此处添加应用逻辑或页面特有样式 -
数据获取限制:
Document
不支持getStaticProps
或getServerSideProps
等数据获取方法
高级用法:自定义 renderPage
对于需要使用 CSS-in-JS 库等高级场景,可能需要自定义 renderPage
方法:
import Document, {
Html, Head, Main, NextScript,
DocumentContext, DocumentInitialProps
} from 'next/document'
class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const originalRenderPage = ctx.renderPage
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => App,
enhanceComponent: (Component) => Component,
})
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="zh-CN">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
高级用法注意事项
getInitialProps
在客户端路由切换时不会被调用- 此模式主要用于集成 CSS-in-JS 库的 SSR 支持
- 对于大多数场景,推荐使用 App Router 而非此高级模式
最佳实践建议
- 保持
_document
尽可能简单,仅包含必要的全局文档结构 - 页面特有内容应放在页面组件或布局组件中
- 对于全局样式,考虑使用
_app
而非_document
- 对于现代项目,优先考虑使用 App Router 而非自定义
_document
通过合理使用自定义 Document,开发者可以更好地控制 Next.js 应用的文档结构,同时保持应用的性能和可维护性。