Пользовательский документ (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
.