カスタム Document
カスタム 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は現在、Next.js の データフェッチングメソッド であるgetStaticPropsやgetServerSidePropsをサポートしていません。
renderPage のカスタマイズ
renderPage のカスタマイズは高度な機能であり、CSS-in-JS のようなライブラリがサーバーサイドレンダリングをサポートする場合にのみ必要です。組み込みの styled-jsx サポートでは必要ありません。
このパターンを使用することは推奨しません。 代わりに、App Router への段階的な移行 を検討してください。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知っておくと良いこと
_documentのgetInitialPropsはクライアントサイド遷移時には呼び出されません。_documentのctxオブジェクトはgetInitialPropsで受け取るオブジェクトと同等ですが、renderPageが追加されています。