Skip to main content

自定义文件

自定义 Document 可以更新用于渲染 页面<html><body> 标签。

¥A custom Document can update the <html> and <body> tags used to render a Page.

要覆盖默认的 Document,请创建文件 pages/_document,如下所示:

¥To override the default Document, create the file pages/_document as shown below:

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>
)
}

很高兴知道:

¥Good to know:

  • _document 仅在服务器上渲染,因此不能在该文件中使用像 onClick 这样的事件处理程序。

    ¥_document is only rendered on the server, so event handlers like onClick cannot be used in this file.

  • 页面正确渲染需要 <Html><Head /><Main /><NextScript />

    ¥<Html>, <Head />, <Main /> and <NextScript /> are required for the page to be properly rendered.

注意事项

¥Caveats

  • _document 中使用的 <Head /> 组件与 next/head 不同。此处使用的 <Head /> 组件只能用于所有页面通用的任何 <head> 代码。对于所有其他情况,例如 <title> 标签,我们建议在你的页面或组件中使用 next/head

    ¥The <Head /> component used in _document is not the same as next/head. The <Head /> component used here should only be used for any <head> code that is common for all pages. For all other cases, such as <title> tags, we recommend using next/head in your pages or components.

  • <Main /> 之外的 React 组件不会被浏览器初始化。不要在此处添加应用逻辑或自定义 CSS(如 styled-jsx)。如果你需要在所有页面中共享组件(例如菜单或工具栏),请阅读 布局

    ¥React components outside of <Main /> will not be initialized by the browser. Do not add application logic here or custom CSS (like styled-jsx). If you need shared components in all your pages (like a menu or a toolbar), read Layouts instead.

  • Document 目前不支持 Next.js 数据获取方法,如 getStaticPropsgetServerSideProps

    ¥Document currently does not support Next.js Data Fetching methods like getStaticProps or getServerSideProps.

自定义 renderPage

¥Customizing renderPage

自定义 renderPage 是高级的,只有像 CSS-in-JS 这样的库才需要支持服务器端渲染。内置 styled-jsx 支持不需要这样做。

¥Customizing renderPage is advanced and only needed for libraries like CSS-in-JS to support server-side rendering. This is not needed for built-in styled-jsx support.

我们不建议使用此模式。相反,请将 逐步采用 视为应用路由,它允许你更轻松地获取 页面和布局 的数据。

¥We do not recommend using this pattern. Instead, consider incrementally adopting the App Router, which allows you to more easily fetch data for 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

// Run the React rendering logic synchronously
ctx.renderPage = () =>
originalRenderPage({
// Useful for wrapping the whole react tree
enhanceApp: (App) => App,
// Useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})

// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx)

return initialProps
}

render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}

export default MyDocument
import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage

// Run the React rendering logic synchronously
ctx.renderPage = () =>
originalRenderPage({
// Useful for wrapping the whole react tree
enhanceApp: (App) => App,
// Useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})

// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx)

return initialProps
}

render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}

export default MyDocument

很高兴知道:

¥Good to know:

  • 在客户端转换期间不会调用 _document 中的 getInitialProps

    ¥getInitialProps in _document is not called during client-side transitions.

  • _documentctx 对象相当于 getInitialProps 中收到的对象,并添加了 renderPage

    ¥The ctx object for _document is equivalent to the one received in getInitialProps, with the addition of renderPage.