schedule2024-05-21

Nextjs App Router での静的サイトのための設定と実装

NexjsのApp RouterでSSGでの静的サイトを構築した際の備忘録。

用意して頂いた環境が良くあるレンタルサーバーだったので、SSGで生成したindex.htmlをURLの通り分けたフォルダに置く必要があった。App Routerで作成して無理ならPagesに戻すつもりで進めたら、意外と何とかなった。

Nextjsのドキュメント | Static Exports

ポイントは以下の通り。

  • next.configの設定

    • output: 'export' : 静的サイトまたはSPAとしてビルドする設定
    • trailingSlash: true : これを設定すると/path.htmlから/path/index.html となる。
  • pages.tsxの実装

    • 'use client' : クライアント側で処理を実行する
    • 動的にURLを生成するためのgenerateStaticParams()の実装

今回は404ページ対応はあきらめた。ドキュメントにはnginxの設定が載っている。

next.configの設定

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  // distDir: 'dist'
  trailingSlash: true,
};

export default nextConfig;

output: 'export'

静的サイトまたはSPAとしてビルドする設定。next buildを実行するとデフォルトではoutディレクトリに出力される。このoutの出力をファイルとフォルダ構成そのままホスティングサービスのルートに置けば静的サイトを公開できる。

outではないディレクトリに出力したい場合はdistDir: 'dist'で書き換えると良い。

trailingSlash: true

階層のあるページ/app/path/to/page.tsxはデフォルトではroot/path/to.htmlのファイルとして出力される。 今回は/path/to/のURLにアクセスしたとき、そのフォルダのindex.htmlを読むウェブサーバーの設定出るため、root/path/to/index.htmlを出力して欲しい。trailingSlash: trueの設定だけで切り替わった。

pages.tsxの実装例

サーバ側はNodeがなくホスティングのみで処理ができないため、pages.tsxファイルの先頭には'use client'を明示してクライアント側で処理する。

pages.tsx
'use client'

export default function Home() {
  return (
    <>{/* ページのコンテンツ */}</>
  );
}

動的なページの場合

お知らせの記事/news/[slug]/のようにページを動的に作るときの書き方。

'use client'は書かない。generateStaticParams()の関数でslugにあたる文字列のリストを作って渡す。

/news/[slug]/page.tsx
// 'use client'は不要。`generateStaticParams()`と競合する。

type Props = {
  params: {
    slug: string;
  };
};

export default function NewsDetail({ params }: Props) {
  return (
    <>{/* ページのコンテンツ */}</>
  );
}

export async function generateStaticParams() {
  const newsList = [{ slug: '2021-01-01' }, { slug: '2021-01-02' }]; // 記事の一覧を取得する処理
  // 静的なパラメータの配列を返す
  return newsList.map((news) => ({
    slug: news.slug,
  }));
}

この書き方では、以下の通りslugがnews配下のフォルダとなってそこにindex.htmlができる。

/
|- news/
   |- 2021-01-01/
      |- index.html
   |- 2021-01-02/
      |- index.html