Next.js で作った Web ページを Cloudflare Pages で公開する(静的エクスポート + GitHub 連携)
Next.js で作った Web ページを、Cloudflare Pages で公開する手順を説明します。前回の記事で作った my-app を例に、静的エクスポート(output: "export")で HTML を書き出し、GitHub のリポジトリと Cloudflare Pages をつなぐところまで進めます。
設定が終わると、GitHub に push するたびに Cloudflare が自動でビルドして公開してくれます。このサイトも同じ構成で公開しています。
この記事でやること
- Next.js の設定を静的エクスポートに変え、手元でビルドを確かめる
- GitHub にリポジトリを作って push する
- Cloudflare Pages のプロジェクトを作り、GitHub と連携してデプロイする
- 公開された
https://<プロジェクト名>.pages.devを確認する
環境
| 項目 | バージョン |
|---|---|
| OS | Windows 11 |
| Node.js | 24.x(LTS) |
| pnpm | 12.x |
| Next.js | 16.4.2 |
| React | 19.3.0 |
| Git | Git 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 する
- GitHub にログインし、新しいリポジトリの作成画面を開く
- Repository name に
my-appなどの名前を入れる - 公開・非公開はどちらでもよい(Cloudflare Pages はどちらにも対応している)
- README や
.gitignoreは追加しない(手元のリポジトリとぶつからないように、空のリポジトリにする) - 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 の公式ドキュメントの表記に合わせています。ダッシュボードの画面は変わることがあるので、名前が違う場合は近い項目を選んでください。
- Cloudflare のダッシュボードにログインし、左のメニューから Workers & Pages を開く
- Create application を押し、Pages のタブを選ぶ
- Import an existing Git repository(Git リポジトリをインポート)を選ぶ
- GitHub を選び、画面の指示に従って Cloudflare に GitHub のリポジトリへのアクセスを許可する(すべてのリポジトリか、
my-appだけかを選べる) - 一覧から
my-appを選び、Begin setup を押す
7. ビルドの設定をする
Set up builds and deployments の画面で、次のように入力します。
| 項目 | 値 |
|---|---|
| Project name | my-app(公開 URL の <プロジェクト名>.pages.dev になる) |
| Production branch | main |
| Framework preset | Next.js (Static HTML Export) |
| Build command | pnpm build |
| Build output directory | out |
| 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_VERSION | package.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 するだけで自動でデプロイされる