カスタム 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 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
が追加されています。