自定义的 Document
可以更新用于呈现页面的 <html>
和 <body>
标签。
要覆盖默认的 Document
,请按照以下示例创建 pages/_document
文件:
tsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
jsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
须知
_document
仅在服务器上渲染,因此不能在此文件中使用onClick
等事件处理器。<Html>
、<Head />
、<Main />
和<NextScript />
是正确渲染页面所必需的。
注意事项
- 在
_document
中使用的<Head />
组件与next/head
不同。此处使用的<Head />
组件仅应用于所有页面共有的<head>
代码。对于其他情况,如<title>
标签,我们建议在页面或组件中使用next/head
。 - 在
<Main />
外部的 React 组件将不会被浏览器初始化。不要在这里添加应用逻辑或自定义 CSS(如styled-jsx
)。如果您需要在所有页面中共享组件(如菜单或工具栏),请阅读 布局。 Document
当前不支持 Next.js 数据获取方法,如getStaticProps
或getServerSideProps
。
自定义 renderPage
自定义 renderPage
是高级操作,仅用于支持服务器端渲染的库,如 CSS-in-JS。对于内置的 styled-jsx
支持,这不是必需的。
我们不推荐使用这种模式。 相反,考虑逐步采用 App Router,这可以让您更轻松地获取页面和布局的数据。
tsx
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
// 同步运行 React 渲染逻辑
ctx.renderPage = () =>
originalRenderPage({
// 有助于包装整个 React 树
enhanceApp: (App) => App,
// 有助于在每个页面的基础上包装
enhanceComponent: (Component) => Component,
})
// 运行父级 `getInitialProps`,现在它包含了自定义的 `renderPage`
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
jsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
// 同步运行 React 渲染逻辑
ctx.renderPage = () =>
originalRenderPage({
// 有助于包装整个 React 树
enhanceApp: (App) => App,
// 有助于在每个页面的基础上包装
enhanceComponent: (Component) => Component,
})
// 运行父级 `getInitialProps`,现在它包含了自定义的 `renderPage`
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
须知
_document
中的getInitialProps
在客户端转换期间不会被调用。_document
的ctx
对象等同于在getInitialProps
中接收到的对象,另外还包括了renderPage
。