Next.js 静的サイト生成 (SSG) と output: ‘export’

目次

SSGの仕組み

従来のSSRやCSRとは異なり、SSGは開発・デプロイ段階でHTMLファイルを完全に生成します。

ユーザーがアクセスする時点では、すでに完成されたHTMLファイルがCDNから即座に配信されるため、極めて高速な表示が実現できます。

SSR、CSR、SSGの違い

  1. SSR: サーバーでHTMLを生成してから送信。初期表示が速く、SEOに有利
SSR (Server-Side Rendering) クライアント ブラウザ Webサーバー Node.js リソース DB・API・ ファイル ①リクエスト ②データ取得 ③データ返却 ④HTML生成&送信 クライアント fetch サーバーでHTMLを完全に生成 ✓ SEO最適化 ✓ 初期表示高速 ✓ 検索エンジンフレンドリー
  1. CSR: クライアント側でJavaScriptが実行されてからDOMを構築。SPAに適している
CSR (Client-Side Rendering) クライアント React/Vue Webサーバー JS/CSS配信 リソース API・DB・ ファイル ①JS取得 ②レスポンス クライアント fetch 高速ですが、大量のデータフェッチだと クライアント依存になってしまうのが…

CSRで動的なページを作成する際は、クライアントfetchとクライアントサイドレンダリングを組み合わせて使用します。

  • CSRの動的ページ作成フロー
    1. クライアント → Webサーバー(JS/CSSファイル取得)
    2. 基本的なHTMLシェルとJavaScriptを受信
    3. クライアントfetch → リソース(API/DB)からデータ取得
    4. 取得したデータを使ってクライアントサイドでレンダリング
    5. DOMを動的に更新してコンテンツを表示
    1. SSG: ビルド時に静的ファイルを生成。最も高速で、CDN配信に最適
    SSG (Static Site Generation) クライアント 即座に表示 Webサーバー 静的配信 リソース DB・API・ ファイルシステム (ビルド時取得) ビルド時 データ取得 静的ファイル 生成完了 ①リクエスト ②高速配信 クライアント fetch ビルド時に全ページを事前生成 (グレー矢印) リクエスト時は高速配信のみ (緑矢印)

    プロジェクトの要件に応じてどの手法を選ぶべきかの参考になるかと思います。

    SSGは「ページを生成する方法」であって、「データを処理する場所」ではない

    サーバーサイドの処理をSSGビルドした場合、どのようになりますか?

    可能。ただし「ビルド時に1回だけ実行される処理」に限られる。

    例)フォームバリデーション

    SSG:ビルド時にHTMLを生成するだけ。「フォーム処理」や「バリデーション処理」の場でもない。

    分類実行場所目的必須か?
    クライアントバリデーションブラウザ内UX向上、即時フィードバック推奨だが任意
    サーバーバリデーションサーバー(API)セキュリティ・整合性保持(改ざん対策)絶対必須

    output: ‘export’ とは

    output: 'export' は Next.js の設定オプションの一つで、プロジェクトを完全に静的なサイトとして生成するための設定です。

    この設定を next.config.js ファイルに追加することで、ビルド時に静的な HTML ファイルが生成され、サーバーサイドの機能を必要としない完全な静的サイトとしてデプロイできるようになります。

    // next.config.js
    module.exports = {
      output: 'export',
    }

    上記設定をしていてもnpm run dev での開発は通常通り行えます (開発サーバーは動作します)

    Next.js: 通常モードと静的エクスポート 通常の Next.js output: ‘export’ 設定: デフォルト 目的: 柔軟性と動的コンテンツの両立 設定: output: ‘export’ 目的: 完全な静的サイト生成 ビルドプロセス • 静的ページは事前レンダリング • 動的ページ用のサーバーコード生成 • API ルートのためのサーバー処理 • クライアント用の JS ファイル生成 ビルドプロセス • すべてのページが静的 HTML に変換 • 動的ルートはすべて事前に定義必須 • API ルートや ISR は使用不可 • 純粋な静的アセットのみを生成 デプロイとホスティング • Node.js サーバーが必要 • サーバーサイド実行環境が必須 • 動的コンテンツに対応可能 デプロイとホスティング • 単純な静的ホスティングで可能 • CDN でのキャッシュに最適 • サーバー不要でコスト削減 柔軟性重視:動的コンテンツ対応 パフォーマンス重視:完全静的サイト

    generateStaticParams() の使い方

    // app/blog/[slug]/page.js
    export async function generateStaticParams() {
      // 例えば、すべてのブログ記事を取得するAPIを呼び出し
      const posts = await fetchPosts();
      
      // 各記事のスラッグをパラメータとして返す
      return posts.map((post) => ({
        slug: post.slug,
      }));
    }
    
    // ページコンポーネント
    export default function BlogPost({ params }) {
      // params.slug が使用可能
      return <div>...</div>;
    }

    この関数が返す配列の各オブジェクトは、1つのルートパスに対応しています。例えば上記のコードでは、posts 配列に含まれる各記事のスラッグに対して静的ページが生成されます。

    なぜ必要なのか?

    output: 'export' を設定すると、Next.js はサイト全体を純粋な静的サイトとしてビルドします。サーバー側のロジックを実行できないため、動的なページ生成ができません。そのため、ビルド時に「どのURLパスをHTMLとして生成するべきか」を明示的に知る必要があるのです。

    これが generateStaticParams() が必要な理由であり、この関数がない場合やすべてのパスが定義されていない場合、ビルド時にエラーが発生します。

    Next.js 静的エクスポートと動的ルート 動的ルートの定義 静的生成結果 app/blog/[slug]/page.js export async function generateStaticParams() { return [ { slug: ‘hello-world’ }, { slug: ‘about-nextjs’ }, { slug: ‘static-export’ } ] } out/ blog/ hello-world/ index.html about-nextjs/ index.html static-export/ index.html

    参考サイト

    静的サイト生成(SSG) | Next.js 日本語ドキュメント
    https://nextjs.org/docs/pages/building-your-application/deploying/static-exports

    この記事を書いた人

    目次