Custom Document
Source URL: https://nextjs.org/docs/pages/building-your-application/routing/custom-document
Custom Document
Section titled “Custom Document”A custom Document can update the <html> and <body> tags used to render a Page.
To override the default Document, create the file pages/_document as shown below:
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> )}Good to know:
_documentis only rendered on the server, so event handlers likeonClickcannot be used in this file.<Html>,<Head />,<Main />and<NextScript />are required for the page to be properly rendered.
Caveats
Section titled “Caveats”- The
<Head />component used in_documentis not the same asnext/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 usingnext/headin your pages or components. - React components outside of
<Main />will not be initialized by the browser. Do not add application logic here or custom CSS (likestyled-jsx). If you need shared components in all your pages (like a menu or a toolbar), read Layouts instead. Documentcurrently does not support Next.js Data Fetching methods likegetStaticPropsorgetServerSideProps.
Customizing renderPage
Section titled “Customizing renderPage”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.
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 MyDocumentimport 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 MyDocumentGood to know:
getInitialPropsin_documentis not called during client-side transitions.- The
ctxobject for_documentis equivalent to the one received ingetInitialProps, with the addition ofrenderPage.