Hayami Kaito Web
~/tech

Next.js で作った Web ページを Cloudflare Pages で公開する(静的エクスポート + GitHub 連携)

published

Next.js で作った Web ページを、Cloudflare Pages で公開する手順を説明します。前回の記事で作った my-app を例に、静的エクスポート(output: "export")で HTML を書き出し、GitHub のリポジトリと Cloudflare Pages をつなぐところまで進めます。

設定が終わると、GitHub に push するたびに Cloudflare が自動でビルドして公開してくれます。このサイトも同じ構成で公開しています。

この記事でやること

  1. Next.js の設定を静的エクスポートに変え、手元でビルドを確かめる
  2. GitHub にリポジトリを作って push する
  3. Cloudflare Pages のプロジェクトを作り、GitHub と連携してデプロイする
  4. 公開された https://<プロジェクト名>.pages.dev を確認する

環境

項目バージョン
OSWindows 11
Node.js24.x(LTS)
pnpm12.x
Next.js16.4.2
React19.3.0
GitGit for Windows

必要なアカウントは次の 2 つです。どちらも無料で作れます。

静的エクスポートと Cloudflare Pages

Next.js は、リクエストのたびにサーバーでページを作る使い方もできますが、ページの中身がビルド時に決まるサイトなら、ビルド時にすべてのページを HTML ファイルとして書き出すこともできます。これが静的エクスポートです。next.config.ts に output: "export" を書くと、pnpm build で out/ フォルダーに HTML・CSS・JavaScript が出力されます。

Cloudflare Pages は、こうした静的なファイルを配信するサービスです。GitHub のリポジトリと連携すると、push を検知してビルドからデプロイまでを自動で行います。

Cloudflare の公式ドキュメントでは、サーバー側の処理も含めて Next.js を動かす場合は Cloudflare Workers を使う方法が勧められています。この記事は、静的エクスポートで済むサイトを Pages で公開する場合の手順です。

静的エクスポートでは、サーバーが必要な機能は使えません。主なものは次のとおりです(一覧は Next.js の公式ドキュメントにあります)。

  • Server Actions("use server")
  • リクエストの内容を読む Route Handlers、cookies() などのリクエスト時の関数
  • next.config.ts の redirects / rewrites / headers
  • 既定のローダーでの画像最適化(next/image)

前回の記事で作ったページ(トップページ・自己紹介ページ・カウンターのボタン)はどれも使っていないので、設定を変えるだけで静的エクスポートできます。

手順

1. next.config.ts を静的エクスポートの設定にする

next.config.ts を次のように変えます。output: "export" を追加し、create-next-app が最初から入れている cacheComponents と partialPrefetching を削除します。

next.config.ts:

 const nextConfig: NextConfig = {
-  /* config options here */
-  cacheComponents: true,
-  partialPrefetching: true,
+  output: "export",
   turbopack: {
     rules: {
       "*.css": {
         loaders: ["@tailwindcss/turbopack"],
         as: "*.css",
       },
     },
   },
 };

cacheComponents と partialPrefetching を残したまま output: "export" を追加すると、ビルドが次のエラーで止まります(理由は「ハマりどころ」で説明します)。

> Build error occurred
Error: Invariant: PPR cannot be enabled in export mode

next/image の <Image /> を使っている場合は、画像最適化のサーバーがないため、images: { unoptimized: true } も追加しておきます。

const nextConfig: NextConfig = {
  output: "export",
  images: {
    unoptimized: true,
  },
  // ...
};

2. 手元でビルドして out フォルダーを確認する

VS Code のターミナルでビルドします。

pnpm build

成功すると、次のように各ページが ○ (Static) として出力されます。

Route (app)
┌ ○ /
├ ○ /_not-found
└ ○ /about


○  (Static)  prerendered as static content

out/ フォルダーに index.html・about.html・404.html などができていれば成功です。out/ を簡易サーバーで配信して、ブラウザで確かめておきます。

pnpm dlx serve out

ターミナルに表示された URL を開き、ボタンが動くこと、/about に移動できることを確認します。確認したら Ctrl+C で止めます。

out/ はビルドのたびに作り直されるフォルダーです。create-next-app で作ったプロジェクトの .gitignore には最初から /out/ が入っているので、Git には含まれません。ビルドは Cloudflare 側で行います。

3. Node.js のバージョンをファイルで指定する

Cloudflare Pages のビルド環境にも Node.js が入っていますが、既定のバージョンは手元と同じとは限りません。プロジェクトのルートに .node-version というファイルを作り、手元と同じメジャーバージョンを 1 行だけ書いておくと、Cloudflare はそのバージョンでビルドします。

.node-version:

24

4. 変更をコミットする

create-next-app でプロジェクトを作ると、Git のリポジトリも作られ、最初のコミットが入っています(ブランチ名は main)。ここまでの変更をコミットします。

git add .
git commit -m "静的エクスポートの設定を追加"

git が「認識されません」と出る場合は、Git for Windows をインストールし、ターミナルを開き直します。初めて使う場合は、コミットの前に git config --global user.name "<your-name>" と git config --global user.email "<your-email>" で名前とメールアドレスを設定します。

5. GitHub にリポジトリを作って push する

  1. GitHub にログインし、新しいリポジトリの作成画面を開く
  2. Repository name に my-app などの名前を入れる
  3. 公開・非公開はどちらでもよい(Cloudflare Pages はどちらにも対応している)
  4. README や .gitignore は追加しない(手元のリポジトリとぶつからないように、空のリポジトリにする)
  5. Create repository を押す

作ったリポジトリの URL を登録して push します。

git remote add origin https://github.com/<your-github-username>/my-app.git
git push -u origin main

初めて push するときは、ブラウザで GitHub へのサインインを求められます。GitHub のリポジトリの画面にファイルが表示されれば完了です。

6. Cloudflare Pages のプロジェクトを作る

ボタン名は Cloudflare の公式ドキュメントの表記に合わせています。ダッシュボードの画面は変わることがあるので、名前が違う場合は近い項目を選んでください。

  1. Cloudflare のダッシュボードにログインし、左のメニューから Workers & Pages を開く
  2. Create application を押し、Pages のタブを選ぶ
  3. Import an existing Git repository(Git リポジトリをインポート)を選ぶ
  4. GitHub を選び、画面の指示に従って Cloudflare に GitHub のリポジトリへのアクセスを許可する(すべてのリポジトリか、my-app だけかを選べる)
  5. 一覧から my-app を選び、Begin setup を押す

7. ビルドの設定をする

Set up builds and deployments の画面で、次のように入力します。

項目値
Project namemy-app(公開 URL の <プロジェクト名>.pages.dev になる)
Production branchmain
Framework presetNext.js (Static HTML Export)
Build commandpnpm build
Build output directoryout
Root directory (advanced)空欄のまま

Framework preset で Next.js (Static HTML Export) を選ぶと、Build command に npx next build、Build output directory に out が入ります。pnpm を使っているので、Build command は pnpm build に書き換えます。

続けて Environment variables (optional) に、pnpm のバージョンを追加します。

変数名値
PNPM_VERSIONpackage.json の packageManager に書かれた pnpm のバージョン(例: [email protected] なら 12.11.2)

package.json を開くと、末尾に次のような行があります。create-next-app を実行したときの pnpm のバージョンが書かれています。

  "packageManager": "pnpm@<version>"

Cloudflare Pages のビルド環境(v3)は、pnpm-lock.yaml から pnpm のバージョンを読み取りません。指定しないと既定のバージョンの pnpm でインストールされるため、手元と同じバージョンを PNPM_VERSION で指定しておきます。

8. デプロイする

Save and Deploy を押すと、最初のビルドが始まります。画面にビルドのログが流れ、依存パッケージのインストール → pnpm build → out/ のアップロードの順に進みます。

完了すると https://<プロジェクト名>.pages.dev という URL が表示されます。開いて、手元で確認したときと同じページが表示されれば公開完了です。

最初のデプロイ直後は、DNS の反映が間に合わずに開けないことがあります。その場合は少し待ってから開き直します。

9. 公開後の動作を確認する

公開された URL で、次の点を確認します。

  • トップページのボタンを押すと数が増える
  • 「自己紹介ページへ」のリンクで /about に移動できる。/about を直接開いても表示される
  • 存在しない URL(例: /nothing)を開くと 404 ページが表示される

Cloudflare Pages は、/about へのアクセスに about.html を返します。また、出力の最上位に 404.html があると、見つからないページにはそれを表示します。Next.js の静的エクスポートはどちらにも合う形でファイルを出力するので、追加の設定は要りません。

更新するときは push するだけ

連携が済んだあとは、ページを変更して main に push するだけで、Cloudflare が自動でビルドし直して公開します。

git add .
git commit -m "トップページの文章を変更"
git push

main 以外のブランチに push すると、本番とは別の URL でプレビューがデプロイされます。公開前の確認に使えます。ビルドの状況や過去のデプロイは、Cloudflare のダッシュボードで Pages のプロジェクトを開くと確認できます。

ハマりどころ

  • Error: Invariant: PPR cannot be enabled in export mode でビルドが止まる: create-next-app が最初から有効にしている cacheComponents は、リクエストのたびに変わる部分をサーバーで描画する仕組み(Partial Prerendering)を前提にしており、静的エクスポートとは一緒に使えません。cacheComponents だけを消すと、今度は `partialPrefetching` requires `cacheComponents` to be enabled というエラーになるので、2 つとも削除します
  • Cloudflare のビルドで依存パッケージのインストールに失敗する: ビルドのログで pnpm のバージョンを確認します。PNPM_VERSION を指定していないと、手元とは違う既定のバージョンの pnpm でインストールされます。packageManager と同じ値になっているか確かめます。環境変数はプロジェクトの Settings から変更でき、変更後は再デプロイが必要です
  • next.config.ts の redirects や headers が効かない: 静的エクスポートでは使えません。Cloudflare Pages では、public/_redirects(リダイレクト)と public/_headers(レスポンスヘッダー)に書くと、out/ にコピーされて Pages が読み込みます

まとめ

  • next.config.ts に output: "export" を書き、cacheComponents と partialPrefetching を削除すると、pnpm build で out/ に静的なファイルが出力される
  • Cloudflare Pages では Framework preset に Next.js (Static HTML Export) を選び、Build command を pnpm build、Build output directory を out にする
  • Node.js は .node-version、pnpm は環境変数 PNPM_VERSION で手元とバージョンを合わせる
  • 連携後は push するだけで自動でデプロイされる

参考