diff --git a/docs/advanced-features/custom-document.md b/docs/advanced-features/custom-document.md
index b6af8d8b18b1e..843f5db272c87 100644
--- a/docs/advanced-features/custom-document.md
+++ b/docs/advanced-features/custom-document.md
@@ -4,76 +4,67 @@ description: Extend the default document markup added by Next.js.
# Custom `Document`
-A custom `Document` is commonly used to augment your application's `` and `
` tags. This is necessary because Next.js pages skip the definition of the surrounding document's markup.
+A custom `Document` can update the `` and `` tags used to render a [Page](/docs/basic-features/pages.md). This file is only rendered on the server, so event handlers like `onClick` cannot be used in `_document`.
-To override the default `Document`, create the file `./pages/_document.js` and extend the `Document` class as shown below:
+To override the default `Document`, create the file `pages/_document.js` as shown below:
```jsx
-import Document, { Html, Head, Main, NextScript } from 'next/document'
-
-class MyDocument extends Document {
- static async getInitialProps(ctx) {
- const initialProps = await Document.getInitialProps(ctx)
- return { ...initialProps }
- }
-
- render() {
- return (
-
-
-
-
-
-
- )
- }
+import { Html, Head, Main, NextScript } from 'next/document'
+
+export default function Document() {
+ return (
+
+
+
+
+
+
+ )
}
-
-export default MyDocument
```
-> The code above is the default `Document` added by Next.js. Feel free to remove the `getInitialProps` or `render` function from `MyDocument` if you don't need to change them.
-
-``, `
+```
-- `renderPage`: `Function` - a callback that runs the actual React rendering logic (synchronously). It's useful to decorate this function in order to support server-rendering wrappers like Aphrodite's [`renderStatic`](https://github.com/Khan/aphrodite#server-side-rendering)
+``, `
+
+
+
+
+ )
+ }
}
export default MyDocument
```
+> **Note**: `getInitialProps` in `_document` is not called during client-side transitions.
+
## TypeScript
You can use the built-in `DocumentContext` type and change the file name to `./pages/_document.tsx` like so:
-
+
`, `` and `` are required for the page to be properly rendered.
-
-Custom attributes are allowed as props, like `lang`:
+The code above is the default `Document` added by Next.js. Custom attributes are allowed as props. For example, we might want to add `lang="en"` to the `` tag:
```jsx
```
-The `
` component used here is not the same one from [`next/head`](/docs/api-reference/next/head.md). The `
` component used here should only be used for any `
` code that is common for all pages. For all other cases, such as `
` tags, we recommend using [`next/head`](/docs/api-reference/next/head.md) in your pages or components.
+Or add a `className` to the `body` tag:
-The `ctx` object is equivalent to the one received in [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md#context-object), with one addition:
+```jsx
+`, `` and `` are required for the page to be properly rendered.
## Caveats
-- `Document` is only rendered in the server, event handlers like `onClick` won't work.
-- React components outside of `` will not be initialized by the browser. Do _not_ add application logic here or custom CSS (like `styled-jsx`). If you need shared components in all your pages (like a menu or a toolbar), take a look at the [`App`](/docs/advanced-features/custom-app.md) component instead.
-- `Document`'s `getInitialProps` function is not called during client-side transitions, nor when a page is [statically optimized](/docs/advanced-features/automatic-static-optimization.md).
+- The `
` component used in `_document` is not the same as [`next/head`](/docs/api-reference/next/head.md). The `
` component used here should only be used for any `
` code that is common for all pages. For all other cases, such as `
` tags, we recommend using [`next/head`](/docs/api-reference/next/head.md) in your pages or components.
+- React components outside of `` will not be initialized by the browser. Do _not_ add application logic here or custom CSS (like `styled-jsx`). If you need shared components in all your pages (like a menu or a toolbar), read [Layouts](/docs/basic-features/layouts.md) intead.
- `Document` currently does not support Next.js [Data Fetching methods](/docs/basic-features/data-fetching/overview.md) like [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) or [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md).
## Customizing `renderPage`
-> It should be noted that the only reason you should be customizing `renderPage` is for usage with **css-in-js** libraries that need to wrap the application to properly work with server-side rendering.
+> **Note:** This 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.
-It takes as argument an options object for further customization:
+To prepare for [React 18](/docs/advanced-features/react-18.md), we recommend avoiding customizing `getInitiaProps` and `renderPage`, if possible.
+
+The `ctx` object shown below is equivalent to the one received in [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md#context-object), with the addition of `renderPage`.
```jsx
-import Document from 'next/document'
+import 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
+ // Useful for wrapping the whole react tree
enhanceApp: (App) => App,
- // useful for wrapping in a per-page basis
+ // Useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})
@@ -82,11 +73,25 @@ class MyDocument extends Document {
return initialProps
}
+
+ render() {
+ return (
+
+
+