NextJS中文文档 - 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:
tsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
jsx
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:
_document
is only rendered on the server, so event handlers likeonClick
cannot be used in this file.<Html>
,<Head />
,<Main />
and<NextScript />
are required for the page to be properly rendered.
Caveats
- The
<Head />
component used in_document
is 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/head
in 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. Document
currently does not support Next.js Data Fetching methods likegetStaticProps
orgetServerSideProps
.
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.
tsx
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 MyDocument
jsx
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
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 MyDocument
Good to know:
getInitialProps
in_document
is not called during client-side transitions.- The
ctx
object for_document
is equivalent to the one received ingetInitialProps
, with the addition ofrenderPage
.