Пользовательский документ (Custom Document)

Пользовательский Document позволяет изменять теги <html> и <body>, используемые для рендеринга страниц (Page).

Чтобы переопределить стандартный 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 /> обязательны для корректного рендеринга страницы.

Ограничения

  • Компонент <Head />, используемый в _document, отличается от next/head. Здесь <Head /> должен использоваться только для кода <head>, общего для всех страниц. Для других случаев, например тегов <title>, рекомендуется использовать next/head в ваших страницах или компонентах.
  • React-компоненты вне <Main /> не будут инициализированы браузером. Не добавляйте сюда логику приложения или пользовательские CSS (например, styled-jsx). Если вам нужны общие компоненты для всех страниц (например, меню или панель инструментов), ознакомьтесь с разделом Макеты (Layouts).
  • Document в настоящее время не поддерживает методы получения данных (Data Fetching methods) Next.js, такие как getStaticProps или getServerSideProps.

Настройка renderPage

Настройка renderPage — это продвинутая функция, необходимая только для таких библиотек, как CSS-in-JS, для поддержки серверного рендеринга. Для встроенной поддержки styled-jsx она не требуется.

Мы не рекомендуем использовать этот подход. Вместо этого рассмотрите возможность постепенного перехода на 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 MyDocument
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

Важно знать

  • getInitialProps в _document не вызывается при клиентских переходах.
  • Объект ctx для _document эквивалентен тому, что получается в getInitialProps, с добавлением renderPage.