introduction

一个自定义的Document通常被使用在应用的<html>以及 <body>标签中,这是必要的,因为Next.js 页面跳过了周围文档的定义 ..

为了避免使用默认的Document,创建一个文件名叫做./pages/_document.js并扩展Document

  1. import Document, { Html, Head, Main, NextScript } from 'next/document'
  2. class MyDocument extends Document {
  3. static async getInitialProps(ctx) {
  4. const initialProps = await Document.getInitialProps(ctx)
  5. return { ...initialProps }
  6. }
  7. render() {
  8. return (
  9. <Html>
  10. <Head />
  11. <body>
  12. <Main />
  13. <NextScript />
  14. </body>
  15. </Html>
  16. )
  17. }
  18. }
  19. export default MyDocument

这上面的代码是Next.js 默认增加的Document, 随便移除getInitialProps或者render函数,如果你不需要改变它们 …

<Html>,<Head/>,<Main/>以及 <Nextscript />是必须的,为了让页面能够正确的渲染 …

自定义属性允许作为props, 例如 lang

<Head />组件并不是等同于next/head的,<Head />组件仅仅能够使用在Document组件中,但是<head>能够应用在各个页面中 …

对于其他的情况,例如<title>标签,我们推荐使用next/head在页面或者组件中 …

这个ctx对象能够等价于在getInitialProps中接收的 …,但是具有一个例外:

  • renderPage: Function 他是一个回调用来实际进行React逻辑(同步),它被用来装饰这个函数为了支持服务器渲染包装器(例如 Aphrodite’s 的renderStatic) …

注意

Document仅仅在服务器上渲染,事件处理器例如onClick不会工作 … ..

  • <Main />外的React 组件将不会被浏览器初始化,不要在这里增加应用逻辑或者自定义CSS(例如styled-jsx),如果你需要在所有页面中共享组件(例如菜单或者工具栏),查看

自定义App

进行替代 …

  • DocumentgetInitialProps 函数将不会在客户端过渡的时候进行调用,或者当一个页面时静态优化的 …
  • Document当前不支持Next.js 数据抓取函数(例如 getStaticProps或者getServerSideProps) …

自定义renderPage

应该注意到仅仅有一种原因进行renderPage的自定义(对于使用了css-in-js的库才需要包装这个应用正确的进行服务端渲染) …

他接收一个选项参数(是一个选项对象) …

  1. import Document from 'next/document'
  2. class MyDocument extends Document {
  3. static async getInitialProps(ctx) {
  4. const originalRenderPage = ctx.renderPage
  5. ctx.renderPage = () =>
  6. originalRenderPage({
  7. // useful for wrapping the whole react tree
  8. enhanceApp: (App) => App,
  9. // useful for wrapping in a per-page basis
  10. enhanceComponent: (Component) => Component,
  11. })
  12. // Run the parent `getInitialProps`, it now includes the custom `renderPage`
  13. const initialProps = await Document.getInitialProps(ctx)
  14. return initialProps
  15. }
  16. }
  17. export default MyDocument

TypeScript

你能够使用内置的DocumentContext类型并改变文件名为./pages/_document.tsx

  1. import Document, { DocumentContext } from 'next/document'
  2. class MyDocument extends Document {
  3. static async getInitialProps(ctx: DocumentContext) {
  4. const initialProps = await Document.getInitialProps(ctx)
  5. return initialProps
  6. }
  7. }
  8. export default MyDocument