Skip to content

自定义文件

¥Custom Document

自定义 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:

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

需要了解:

¥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.

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

    // 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
jsx
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.

Next.js v15.2 中文网 - 粤ICP备13048890号