カスタムドキュメント
カスタム Document
を使用すると、ページをレンダリングする際に使用される <html>
タグと <body>
タグを更新できます。
デフォルトの 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 />
はページを正しくレンダリングするために必須です。
注意点
_document
で使用される<Head />
コンポーネントはnext/head
とは異なります。ここで使用する<Head />
コンポーネントは、すべてのページに共通する<head>
コードのみに使用してください。<title>
タグなどの他のケースでは、ページやコンポーネント内でnext/head
を使用することを推奨します。<Main />
の外側にあるReactコンポーネントはブラウザによって初期化されません。ここにアプリケーションロジックやカスタムCSS(styled-jsx
など)を追加しないでください。すべてのページで共有コンポーネント(メニューやツールバーなど)が必要な場合は、代わりにレイアウトを参照してください。Document
は現在、getStaticProps
やgetServerSideProps
といったNext.jsのデータフェッチング方法をサポートしていません。
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 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
知っておくと良いこと
_document
のgetInitialProps
はクライアントサイドの遷移時には呼び出されません。_document
のctx
オブジェクトはgetInitialProps
で受け取るオブジェクトと同等ですが、renderPage
が追加されています。