---
title: "Cloudflare PagesでNext.jsの静的サイトを無料公開してみる"
description: "Next.jsで作った静的サイト「戦略の系譜」をCloudflare Pagesへデプロイし、ローカル確認、ビルド、wrangler設定、Productionデプロイ、独自ドメイン公開までを確認した実験ログ。"
lang: "ja"
canonical: "https://llm-lab.dev/posts/cloudflare-pages-static-site-deploy/"
source: "https://llm-lab.dev/posts/cloudflare-pages-static-site-deploy.md"
publishedAt: "2026-04-11"
updatedAt: "2026-06-17"
category: "Cloudflare"
tags:
  - "cloudflare"
  - "cloudflare-pages"
  - "nextjs"
  - "static-site"
---

# Cloudflare PagesでNext.jsの静的サイトを無料公開してみる

import LinkCard from "../../components/LinkCard.astro";

> [!NOTE]
> この記事で確認したこと
>
> 今回は、Next.jsの静的出力をCloudflare Pagesで公開する流れを、ローカル表示、ビルド、sitemap生成、Wrangler設定、Productionデプロイ、独自ドメイン表示まで通して確認しました。
>
> 結果として、Cloudflare PagesはNext.js静的サイトの公開先として十分使えました。ただし、Dashboardだけでは設定の全体像が見えにくい場面があるため、`pages_build_output_dir = "out"` のような出力先、sitemap生成、デプロイ設定はリポジトリ内で確認できる形にしておく必要があります。

## はじめに

個人開発を始めると、最初に地味に詰まるのが公開環境です。

アプリ本体を作る前に、LPを置きたい。技術ブログを公開したい。小さなメディアサイトを試したい。そう思っても、いざ公開しようとすると、ホスティング、独自ドメイン、SSL、ビルド設定、環境変数、デプロイ方法など、細かい判断が一気に出てきます。

VercelやNetlifyを使えばすぐに公開できます。ただ、Cloudflare Pagesもかなり強い選択肢です。静的サイトであれば、無料枠で公開しやすく、独自ドメインも扱いやすく、CloudflareのCDN上で配信できます。

今回は、実際に自分で公開したサイトを題材にして、Cloudflare Pagesで静的サイトを公開する流れを確認します。

対象にするのは、次のサイトです。


<LinkCard
  href="https://bukei-wisdom.com/"
  title="戦略の系譜"
  description="歴史的英雄たちの戦略決断を古典の教えで分析し、現代への応用を探る知恵の宝庫"
  siteName="https://bukei-wisdom.com/"
  image="https://bukei-wisdom.com/images/og-default.webp"
/>

「戦略の系譜」という、東洋古典や兵法書を扱う静的サイトです。実装はNext.jsで、Cloudflare Pagesへデプロイしています。

## 今回公開したもの

今回公開したのは、Next.jsで作った静的サイトです。

```text
Browser
  ↓
Cloudflare Pages
  ↓
Next.js static export
```

対象プロジェクトは、手元では「戦略の系譜」プロジェクトの `app` 配下にあります。

```text
bukei_shichisyo/
```

アプリ本体は `app` 配下です。

```text
bukei_shichisyo/
  app/
    package.json
    wrangler.toml
    out/
```

今回確認したことは、次の6つです。

* ローカルでNext.jsサイトを表示できるか
* Next.jsの静的ビルドが通るか
* sitemapが生成されるか
* Cloudflare Pages向けの出力先が `out` になっているか
* Cloudflare PagesのProductionデプロイが成功しているか
* 独自ドメイン `bukei-wisdom.com` で表示できるか

最初から結論を書くと、Cloudflare PagesでNext.jsの静的サイトを公開する流れは成立しました。

ただし、Cloudflare Dashboard上でBuild commandやRoot directoryが常に分かりやすく見えるわけではありませんでした。今回はWrangler CLIと `wrangler.toml` の設定を根拠に、デプロイ構成を確認しています。

## なぜCloudflare Pagesを使うのか

静的サイトの公開先としては、Vercel、Netlify、GitHub Pagesなど、いくつか選択肢があります。

その中でCloudflare Pagesを使う理由は、Cloudflareの他サービスへ広げやすいからです。

最初は静的サイトだけで十分です。しかし、個人開発を続けていると、問い合わせフォーム、画像配信、API、認証、Bot対策、AI機能などを後から足したくなります。

Cloudflare Pagesを入口にしておくと、Workers、R2、KV、D1、Turnstile、AI Gatewayなどに広げやすいです。最初から全部使う必要はありませんが、あとから拡張できる余地があるのは安心です。

今回の「戦略の系譜」も、まずは静的サイトとして公開するところに絞りました。DBや認証は扱わず、公開環境としてCloudflare Pagesが使えるかを確認します。

## ローカルで確認する

まず、手元でNext.jsサイトを表示します。

```bash
cd bukei_shichisyo/app
npm install
npm run dev
```

ローカルでは `localhost:3000` で表示しました。

![ローカルで表示した戦略の系譜](/images/posts/cloudflare-p1-001-pages-static-site/01-local-site.webp)

ここで確認したのは、サイトのデザインそのものではありません。Cloudflare Pagesへ出す前に、少なくともローカルでトップページが表示でき、主要なナビゲーションやカードが崩れていないことを確認しました。

公開環境の問題を調べる前に、ローカルで成立している状態を残しておくと、後で切り分けがしやすくなります。

## ビルドする

次に、本番向けにビルドします。

```bash
npm run build
```

このプロジェクトでは、`build` 後に `next-sitemap` が走るようになっています。

`package.json` では、次のようなscriptになっています。

```json
{
  "scripts": {
    "build": "next build",
    "postbuild": "next-sitemap"
  }
}
```

実際にビルドすると、`next-sitemap` の生成完了まで確認できました。

![Next.jsビルドとsitemap生成の成功ログ](/images/posts/cloudflare-p1-001-pages-static-site/02-build-success.webp)

スクリーンショットでは、`https://bukei-wisdom.com/sitemap.xml` が生成対象として表示されています。

ここは地味ですが重要です。静的サイトを公開するだけなら、HTMLが表示されれば最低限は成立します。しかし、検索流入を考えるなら、sitemapまで生成されているかは確認しておきたいところです。

## Cloudflare Pages向けの設定

Cloudflare Pages向けの設定は、`app/wrangler.toml` にあります。

```toml
name = "bukei-wisdom"
compatibility_date = "2024-01-15"
pages_build_output_dir = "out"
compatibility_flags = ["nodejs_compat"]

[env.production]
name = "bukei-wisdom"
compatibility_flags = ["nodejs_compat"]

[env.preview]
name = "bukei-wisdom-preview"
compatibility_flags = ["nodejs_compat"]
```

実際の設定画面は次の通りです。

![Cloudflare Pages用のwrangler設定](/images/posts/cloudflare-p1-001-pages-static-site/03-wrangler-config.webp)

ここで特に見るべきなのは、次の2つです。

```toml
name = "bukei-wisdom"
pages_build_output_dir = "out"
```

`name` はCloudflare Pagesのプロジェクト名です。`pages_build_output_dir` は、Cloudflare Pagesへデプロイする静的ファイルの出力先です。

今回のプロジェクトでは `out` を使っています。Astroであれば `dist` がよく出ますが、Next.jsの静的出力では構成によって `out` を使います。ここを間違えると、ビルドは通っているのにCloudflare Pages側で配信対象が見つからない、という状態になります。

## デプロイしてみる

Cloudflare Pages側には、`bukei-wisdom` というプロジェクトとして作成されています。

![Cloudflare Pagesのbukei-wisdom設定画面](/images/posts/cloudflare-p1-001-pages-static-site/04-cloudflare-pages-project.webp)

今回の運用では、Cloudflare Dashboard上のBuild commandやRoot directoryの詳細値は確認できませんでした。Git連携のビルド設定画面というより、Wrangler CLI中心のPagesデプロイ運用になっているためです。

そのため、記事ではDashboardのBuild settingsではなく、次の2つを根拠にします。

* `wrangler.toml` の `pages_build_output_dir = "out"`
* `package.json` のCloudflare Pages向けscript

`package.json` には、Cloudflare Pages向けに次のscriptがあります。

```json
{
  "scripts": {
    "pages:build": "npx @cloudflare/next-on-pages",
    "pages:deploy": "npm run pages:build && wrangler pages deploy",
    "deploy:production": "npm run build && npm run pages:build && wrangler pages deploy"
  }
}
```

デプロイは、基本的には次の流れです。

```bash
npm run build
npm run pages:build
wrangler pages deploy
```

または、scriptにまとめたコマンドを使います。

```bash
npm run deploy:production
```

Cloudflare PagesのProduction deploymentは成功しており、`bukei-wisdom.com` と `bukei-wisdom.pages.dev` が紐づいています。

![Cloudflare PagesのProductionデプロイ成功画面](/images/posts/cloudflare-p1-001-pages-static-site/06-deploy-success.webp)

この画面では、Production環境、mainブランチ、デプロイ成功status、公開ドメインを確認できます。

## 独自ドメインで表示する

最後に、独自ドメインで表示できるかを確認します。

今回の本番URLは次の通りです。

```text
https://bukei-wisdom.com/
```

実際にアクセスすると、Cloudflare Pages経由で「戦略の系譜」のトップページが表示されました。

![bukei-wisdom.comで公開された戦略の系譜](/images/posts/cloudflare-p1-001-pages-static-site/09-bukei-wisdom-production.webp)

PagesのProduction deployment画面でも、次の2つのドメインが確認できます。

```text
bukei-wisdom.com
bukei-wisdom.pages.dev
```

Cloudflare Pagesでは、`pages.dev` のURLだけでも公開できます。しかし、検索やSNS共有、サイトとしての見え方を考えると、独自ドメインを設定した方が扱いやすくなります。

今回も、最終的には `bukei-wisdom.com` を主URLとして使う前提にしています。

## 実際に詰まりやすいところ

実際に確認して、Cloudflare Pagesで静的サイトを出すときに注意すべき点は3つありました。

1つ目は、出力ディレクトリです。

Astroなら `dist`、Next.jsの静的出力なら `out` のように、フレームワークや構成によって配信対象のディレクトリが変わります。今回の設定では、`wrangler.toml` の `pages_build_output_dir = "out"` が重要でした。

2つ目は、Cloudflare Dashboardで見える情報と、実際のデプロイ運用が一致しないことです。

Git連携のBuild settingsを使っている場合は、Build commandやRoot directoryがDashboardで見やすいです。一方で、Wrangler CLI中心でデプロイしている場合は、Dashboardだけを見てもすべての設定が分かるとは限りません。今回は、`wrangler.toml` と `package.json` のscriptを見て、デプロイ構成を確認しました。

3つ目は、sitemapです。

サイトが表示されるだけなら、sitemapは必須ではありません。しかし、検索流入を期待するなら、`sitemap.xml` が生成されているかを確認した方がよいです。今回のビルドログでは、`next-sitemap` によって `https://bukei-wisdom.com/sitemap.xml` が生成対象になっていることを確認できました。

## この記事で分かったこと

Cloudflare Pagesは、Next.jsの静的サイトを公開する先として十分使えます。

今回の実例では、ローカル表示、Next.jsビルド、sitemap生成、Wrangler設定、Productionデプロイ、独自ドメイン表示まで確認できました。

特に、`wrangler.toml` に `pages_build_output_dir = "out"` を明示しておくと、Cloudflare Pagesへ何を配信するのかが分かりやすくなります。Dashboardだけで設定を追おうとすると見えない部分もあるため、リポジトリ内に設定を残しておくことは重要です。

個人開発では、サイトを作ることよりも、公開して継続的に直せる状態を作ることが大事です。

Cloudflare Pagesで一度公開まで通しておくと、その後にWorkers、R2、D1、Turnstile、AI Gatewayなどへ広げる足場になります。今回の「戦略の系譜」は静的サイトとして公開しましたが、将来的にフォーム、分析、AI機能を足す場合にも、Cloudflare上に置いてあることは拡張しやすさにつながります。

ぼやきとしては、検証記事を証跡が足りない状態で公開してしまうのはよくないです。検証記事は、やはり動かした画面やログまで揃えてから出した方が強いです。
