mayuzu.me
← トップページに戻る

Next.jsのレンダリング方式:SSG(Static Site Generation)

#Next.js

Next.js v15.3.5時点でのApp RouterにおけるSSGについての学習メモです。

基本的な静的ページ

App Routerでは可能な限り静的なページとしてレンダリングされる。 例えばこのブログではトップとaboutページは静的なものという判断になる。

Route (app)                                 Size  First Load JS  Revalidate  Expire
┌ ○ /                                      175 B         104 kB          1h      1y
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
└ ○ /about                               5.49 kB         110 kB
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
○  (Static)  prerendered as static content
●  (SSG)     prerendered as static HTML (uses generateStaticParams)

試しにaboutページに

export const dynamic = "force-dynamic";

を入れたところサーバーレンダリングとなった。

└ ƒ /about                               5.49 kB         110 kB
ƒ  (Dynamic)  server-rendered on demand

ビルド時にHTMLとして生成されるため初期表示を最も早く実現することができる。 また、トップページにようにAPIから取得する場合でもキャッシュができており、リクエストヘッダーの情報を取得するよう動的な作りでは無い限り静的なページとしてレンダリングされる。

動的ルートでの静的ページ

動的なルート、例えば(/blogs/[id])のようなルートで静的サイトを生成する場合はgenerateStaticParams関数とdynamicParamsという設定を使用する。

dynamicParamsはRoute Segment Configと呼ばれるものの一つで、直接exportとして定義することでページの挙動を設定することができる。dynamicParamsはbooleanで、trueが設定されるとgenerateStaticParamsで事前生成されていないパスにアクセスがあった時、サーバー上でレンダリングし、その結果をキャッシュする。falseだとレンダリングはされず404となる。 デフォルトはtrueとなっている。

Route Segment Config

// /app/blogs/[id]
export const dynamicParams = true;

export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts').then(res => res.json());

  return posts.map((post: any) => ({
    id: post.id.toString(), // ここで動的ページのIDパスに対応したプロパティでIDの一覧を返す
  }));
}

export default async function PostPage({ params }: { params: { id: string } }) {
  const post = await fetch(`https://api.example.com/posts/${params.id}`)
    .then(res => res.json());

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

記事データを取得するような静的ページでは生成時に何らかの原因でデータが取得できずエラーで生成するとそれがキャッシュされてしまう。なのでエラー時はキャッシュしない・revalidateを設定するなどといった考慮をする必要がある。

Tips💡 : generateStaticParamsを設定しないとbuild時に生成されず、アクセスがある度生成されキャッシュされるようになる。さらにその状態でdynamicParamsがfalseだと全て404になる。

サイト全体の静的サイト化

next.config.jsにoutput: 'export'を設定することで静的ファイルとして出力することができる。これにより、AWS S3などに配置することでホスティングが可能になる。

また、サーバー上で動作させる必要のあるものなどは使用することができない。

How to create a static export of your Next.js application

next.config.jsで次のような設定を行い、next buildを実行するとout/が作成されるのでそれを配置すればよい。

// next.config.js
const nextConfig = {
  output: 'export'
}