Next.js SSGの基本をわかりやすく解説: 高速な静的サイト構築のメリットや実装手順を紹介

はじめに

皆さんはWebサイトを作り始めるとき、どのようにページを表示すればよいのか悩むことはないでしょうか。 とくに初心者の方は、サーバーサイドでのレンダリングやクライアントサイドでのレンダリングなど、さまざまな手法があるので迷いやすいかもしれません。 そこで登場するのが Next.js SSG (Static Site Generation) という方法です。 HTMLをビルド時に生成しておくことで、高速な表示やセキュリティの向上を期待できます。 ここでは、Next.jsの最新バージョン(Next.js 13)を前提に、SSGの基本から実装、さらに実務での活用シーンまでをわかりやすく解説していきます。

Next.js SSGとは

SSG (Static Site Generation) は、ビルド時に必要なHTMLファイルをあらかじめ生成し、それをホスティングする仕組みです。 一般的なHTMLの静的ホスティングと同じように見えますが、Next.jsが用意する機能を使うことで、Reactコンポーネントを使いながらビルド時にHTMLを出力できる点が特徴です。 この仕組みによって、リクエストが発生するたびにサーバーで処理をする必要がなくなり、多数のアクセスが集中した場合でも安定しやすい傾向にあります。 ブログや企業サイトなど、ページ内容の更新頻度が高くないケースに活用することが多いです。

SSGを利用するメリット

Next.js SSGには、さまざまなメリットがあります。 まず、ページ表示速度の向上 です。 静的ファイルとして提供されるため、CDNなどにキャッシュを置きやすくなり、ユーザーがアクセスしたときの読み込みが速くなります。 また、HTMLがあらかじめ生成されるので、SEO(検索エンジン最適化)の面でも効果が期待できる場合があります。

もう一つのポイントは、セキュリティ面 です。 ページが静的ファイルとして生成されるので、Webサーバー上でアプリケーションロジックを実行することがありません。 その結果、サーバーサイドの脆弱性を突かれるリスクを減らせます。

ビルド時のデータ取得の流れ

Next.js SSGでは、ビルド時にデータを取得してページを生成する流れが大事になります。 たとえばREST APIや外部サービスから情報を取得したい場合、Next.js 13のApp Router では generateStaticParamsfetch を用いてデータをビルド時に取得できます。 ビルドプロセスで受け取ったデータをもとに、HTMLファイルがビルド後に出力される仕組みです。 ここで生成されたHTMLは静的なファイルなので、ユーザーはビルド後すぐに表示できます。

このとき、よほど頻繁に変わるコンテンツでなければ、SSGが大きな効果を発揮する可能性があります。 もし動的に変化するデータが多い場合は、SSGよりもSSRやISRを検討するケースもあります。

実務での活用シーン

SSGは実務でもいろいろな場面で活用されます。 たとえば、企業の製品紹介ページやブログのように、更新頻度が低いページではSSGが向いています。 一度ビルドしてしまえば、アクセス数が増えてもサーバー負荷が上がりにくく、運用コストを抑えられるからです。

また、いわゆるマーケティング系のランディングページでもよく使われます。 ページ数は多いけれど、コンテンツの更新頻度が高くない場合には、SSGが効率的といえるでしょう。 ただし、頻繁に在庫が変わる大規模ECサイトなどでは、リアルタイム性を確保するためにSSRやCSRを組み合わせることがあります。

SSGはページ数が膨大になるほどビルド時間も長くなりやすいです。 大規模サイトでは分割してビルドする方法を考えたり、ISR(Incremental Static Regeneration)を検討したりするのが一般的です。

SSGの実装例

Next.js 13以降ではApp Routerを使った構成が注目を集めています。 ここでは簡単なブログページを例に、実装の流れを見てみましょう。 あくまでシンプルな例ですが、実務でも使えるヒントがあるかもしれません。

ディレクトリ構成

新しいApp Routerを利用する場合、app フォルダ配下にページファイルなどを配置します。 下記のような構成例を考えてみてください。

my-blog/
├─ app/
│   ├─ layout.tsx
│   ├─ page.tsx
│   └─ posts/
│       ├─ [slug]/
│       │   └─ page.tsx
│       └─ page.tsx
├─ public/
├─ package.json
└─ next.config.js

posts/[slug]/page.tsx で動的なパスを扱う場合は、パラメータごとに静的ファイルが生成されます。 そのため、事前に投稿記事の情報を用意しておくことで、ビルド時に各ページをまとめて生成することができます。

コードサンプル

以下は posts/[slug]/page.tsx の一例です。 パラメータを取得して静的ページを生成する際に、generateStaticParams を活用しています。

// app/posts/[slug]/page.tsx
import { notFound } from "next/navigation";

type Post = {
  slug: string;
  title: string;
  content: string;
};

// ここでビルド時に全てのパラメータを取得しておく
export async function generateStaticParams() {
  const posts: Post[] = await getAllPosts(); // 外部APIやDBから記事一覧を取得
  return posts.map((post) => ({
    slug: post.slug,
  }));
}

// 取得したパラメータでページを生成
export default async function PostPage({ params }: { params: { slug: string } }) {
  const { slug } = params;
  const post = await getPostBySlug(slug); // 記事データをフェッチ

  if (!post) {
    return notFound();
  }

  return (
    <main>
      <h2>{post.title}</h2>
      <p>{post.content}</p>
    </main>
  );
}

// ダミーのデータ取得関数
async function getAllPosts(): Promise<Post[]> {
  return [
    { slug: "hello-world", title: "Hello World", content: "ブログの記事内容" },
    { slug: "sample-post", title: "サンプル記事", content: "サンプルのテキストです" },
  ];
}

// ダミーの個別記事取得関数
async function getPostBySlug(slug: string): Promise<Post | null> {
  const allPosts = await getAllPosts();
  return allPosts.find((post) => post.slug === slug) || null;
}

このように、ビルド時に必要なパラメータをあらかじめ取得して、ページごとの静的ファイルを生成します。 動的なパスでもビルド済みのHTMLとして提供されるので、アクセスした瞬間にページが表示されやすいです。

SSGを運用するうえでの注意点

SSGでは、ビルドが終わった段階でページが完成しています。 そのため、新しいコンテンツを追加するときには改めてビルドを行う必要があります。 更新タイミングが決まっている場合には問題になりませんが、不規則に更新するサイトでは運用フローを考える必要があるかもしれません。

もう一つは、APIの変更やレイアウトの更新 など、ビルドロジックに関わる修正があった場合です。 SSGの場合は再ビルドしない限り、新しいコンテンツや修正が反映されません。 そのため、更新作業のたびにビルドが走る点は理解しておく必要があります。

大量のページを一括ビルドすると時間がかかる傾向があります。 ビルド時間が長くなる場合は、ページごとの生成方法やISRの導入を検討するなど、運用コストを考慮してください。

SSGと他のレンダリング手法の比較

Next.jsでは、SSG, SSR, CSR と複数の手法を選択できます。 ここで、それぞれの特徴を比べてみましょう。

レンダリング手法特徴データ取得のタイミング
SSGビルド時にHTMLを生成ビルド時
SSRリクエストごとにHTMLを生成リクエスト時
CSR画面読み込み後にJSで描画クライアントサイド

SSGは一度ビルドすれば高速にページを配信できる反面、更新時の再ビルドが必要です。 SSRはリアルタイムでHTMLを生成しますが、サーバーへの負荷と速度が気になるかもしれません。 CSRはクライアントサイドのみで処理するため表示速度が不安定になることがありますが、動的なUIの自由度は高いです。

まとめ

Next.js SSGを使うことで、静的ファイルとしての配信が可能になり、速度やセキュリティ面のメリットを享受できます。 更新頻度の低いサイトや、多くのアクセスを一括でさばきたい場合にはとくに有用ではないでしょうか。 ただし、サイトの規模が大きくなればビルド時間や更新フローなどの課題も発生するため、SSRやISRを含めた方法との比較が大切です。

皆さんがSSGを活用するうえで、ビルド時のデータ取得やコードの書き方に慣れておくと、運用が格段にスムーズになります。 初心者の方でも、実際にプロジェクトを立ち上げてみると、Next.js SSGの利便性がよく分かるのではないでしょうか。

Next.jsをマスターしよう

この記事で学んだNext.jsの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。