自定义 Document
自定义 Document 可以更新用于渲染页面 (Page) 的 <html> 和 <body> 标签。
要覆盖默认的 Document,请按以下方式创建 pages/_document 文件:
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}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)。如果需要在所有页面中共享组件(如菜单或工具栏),请参阅布局 (Layouts)。Document目前不支持 Next.js 的数据获取方法 (Data Fetching methods),如getStaticProps或getServerSideProps。
自定义 renderPage
自定义 renderPage 是高级用法,通常仅用于支持服务端渲染的 CSS-in-JS 等库。内置的 styled-jsx 不需要此操作。
我们不推荐使用此模式。 相反,建议考虑逐步采用 (incrementally adopting) App Router,它可以更轻松地为页面和布局 (pages and layouts) 获取数据。
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 MyDocumentimport 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。