Пользовательский документ (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 />не будут инициализированы браузером. Не добавляйте сюда логику приложения или пользовательские стили (например,styled-jsx). Если вам нужны общие компоненты на всех страницах (например, меню или панель инструментов), ознакомьтесь с разделом Макеты (Layouts). Documentв настоящее время не поддерживает методы получения данных (Data Fetching) Next.js, такие какgetStaticPropsилиgetServerSideProps.
Настройка renderPage
Настройка renderPage — это продвинутая функциональность, необходимая только для библиотек вроде CSS-in-JS для поддержки серверного рендеринга. Для встроенной поддержки styled-jsx это не требуется.
Мы не рекомендуем использовать этот подход. Вместо этого рассмотрите возможность постепенного перехода на App Router, который позволяет проще получать данные для страниц и макетов.
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 MyDocumentimport 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.