1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsの_document.tsx とは何か

1
Posted at

Next.js の _document.tsx とは何か

概要

_document.tsx は Next.js におけるHTMLドキュメント全体の構造を定義するファイルです。
通常のReactプロジェクトにある index.html<html><body> タグを含むファイル)に相当する役割を担います。

コード全体

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";

Next.js が提供する4つの専用コンポーネントをインポートしています。
これらはページを正しくレンダリングするためにすべて必須です。

コンポーネント 役割
Html <html> タグに対応。lang 属性などを設定できる
Head <head> タグに対応。全ページ共通のメタ情報やフォント読み込みを記述する
Main ページ本体がレンダリングされる場所(_app.tsx の出力がここに入る)
NextScript Next.js が動作するために必要なスクリプトを挿入する

Document コンポーネント本体

export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

この構造は、通常のHTMLファイルの骨格と対応しています。

<Html>        →  <html>
  <Head />    →  <head>...</head>
  <body>      →  <body>
    <Main />       →  ページの中身
    <NextScript /> →  Next.js のスクリプト群
  </body>     →  </body>
</Html>       →  </html>

_app.tsx との違い

_document.tsx_app.tsx は似ているようで、役割が明確に異なります。

比較項目 _document.tsx _app.tsx
担当範囲 HTMLドキュメント全体(<html>, <head>, <body> ページコンポーネントの初期化
実行環境 サーバーサイドのみ サーバーサイド+クライアントサイド
イベントハンドラ onClick などは使えない 使える
グローバルCSS インポートできない インポートできる(唯一の場所)
状態管理 できない Context Provider などを設置できる

処理の流れにおける位置づけ

ユーザーがページにアクセス
  ↓
_document.tsx が HTML の骨格を生成(サーバーサイド)
  ↓
_app.tsx が Component(ページ)を初期化
  ↓
該当ページのコンポーネントがレンダリング
  ↓
完成した HTML がブラウザに送信される

なぜ _document.tsx が必要なのか

通常の React プロジェクトでは public/index.html<html><body> タグを直接書きます。
しかし Next.js には index.html が存在しません。

Next.js はこの HTML の骨格をフレームワーク内部で自動生成していますが、
それをカスタマイズしたい場合に _document.tsx を使います。

つまり、_document.tsxNext.js が隠している index.html を上書き(オーバーライド)するためのファイルです。

Head(next/document)と Head(next/head)の違い

Next.js には2つの Head コンポーネントがあるため、混同しやすいポイントです。

項目 next/documentHead next/headHead
使う場所 _document.tsx のみ 各ページコンポーネント内
用途 全ページ共通<head> 内容 ページごと<head> 内容
使用例 Webフォントの読み込み、共通メタタグ ページ固有の <title>、OGP設定
// _document.tsx 内(全ページ共通)
<Head>
  <link
    href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap"
    rel="stylesheet"
  />
</Head>
// pages/about.tsx 内(このページだけ)
import Head from "next/head";

export default function About() {
  return (
    <>
      <Head>
        <title>About | MySite</title>
        <meta name="description" content="About ページの説明" />
      </Head>
      <h1>About</h1>
    </>
  );
}

_document.tsx の代表的な使い方

デフォルトの状態は最小構成です。実際のプロジェクトでは以下のようなカスタマイズを行います。

import { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  return (
    <Html lang="ja">
      <Head>
        {/* Google Fonts の読み込み */}
        <link
          href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap"
          rel="stylesheet"
        />
        {/* ファビコンの設定 */}
        <link rel="icon" href="/favicon.ico" />
        {/* 全ページ共通のメタタグ */}
        <meta name="theme-color" content="#ffffff" />
      </Head>
      <body className="antialiased">
        {/* ダークモード用のフラッシュ防止スクリプト */}
        <script dangerouslySetInnerHTML={{ __html: `/* theme script */` }} />
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}
用途 概要
lang 属性の設定 <Html lang="ja"> でページの言語を指定
Webフォントの読み込み Google Fonts などの外部フォントを全ページに適用
ファビコンの設定 サイトのアイコンを指定
共通メタタグ theme-colorcharset など全ページに必要なメタ情報
body へのクラス付与 Tailwind CSS の antialiased など
初期化スクリプトの挿入 ダークモードのちらつき防止など、レンダリング前に実行したいスクリプト

注意点

  • _document.tsxサーバーサイドでのみレンダリングされる。onClick などのイベントハンドラは動作しない
  • <Html>, <Head />, <Main />, <NextScript /> の4つは削除してはいけない(ページが正しくレンダリングされなくなる)
  • アプリケーションのロジックや styled-jsx などの CSS-in-JS は _document.tsx に書かず、_app.tsx に書く
  • グローバル CSS のインポートは _document.tsx ではなく _app.tsx で行う

まとめ

  • _document.tsx は Next.js が隠している HTML の骨格(<html>, <head>, <body>)をカスタマイズするファイル
  • サーバーサイドでのみ実行され、クライアントサイドのイベントは使えない
  • _app.tsx が「ページの初期化」を担当するのに対し、_document.tsx は「HTMLドキュメントの構造」を担当する
  • next/documentHeadnext/headHead は別物なので注意
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?