Cloudflare Pagesの使い方を実体験ベースで徹底解説。Vercel・Netlifyとの比較、プロジェクト作成手順、カスタムドメイン設定、Functions(サーバーレスAPI)、運用Tipsまで。
個人開発
公開: by ToolCraft Lab 約7分で読めます

Cloudflare Pages 完全ガイド — 無料で始めるWebサイトデプロイ&運用術【2026年版】

Cloudflare Pagesの使い方を実体験ベースで徹底解説。Vercel・Netlifyとの比較、プロジェクト作成手順、カスタムドメイン設定、Functions(サーバーレスAPI)、運用Tipsまで。

#Cloudflare Pages#デプロイ#ホスティング

Cloudflare Pages で「無料なのに本格的」なデプロイ環境を手に入れる

「個人開発のサイトをデプロイしたいけど、Vercel の帯域制限が気になる…Netlify のビルド時間が足りない…」 Cloudflare Pages なら、無料プランでも帯域制限なし・ビルド回数500回/月という破格の条件で運用できます。

この記事では、実際に当サイト(toolcraftlab.dev)を Cloudflare Pages で運用している経験をベースに、セットアップから本番運用までを解説します。


Cloudflare Pages とは

Cloudflare Pages は、Cloudflare のグローバルCDNネットワーク上で静的サイトやフルスタックアプリケーションをホスティングするプラットフォームです。

主な特徴

  • 無料で帯域無制限: 他のプラットフォームとの最大の差別化ポイント
  • グローバルCDN: 世界300以上のデータセンターからコンテンツ配信
  • Git 連携: GitHub / GitLab からの自動デプロイ
  • プレビューデプロイ: PR ごとにプレビューURLが自動生成
  • Functions: サーバーレスAPI(Cloudflare Workers ベース)
  • カスタムドメイン: SSL 証明書も自動発行

Vercel・Netlify との比較

無料プランの比較

項目Cloudflare PagesVercelNetlify
帯域制限無制限100GB/月100GB/月
ビルド回数500回/月6,000分/月300分/月
同時ビルド111
ファイルサイズ上限25MB/ファイルなしなし
サイト数無制限無制限500
サーバーレス関数Workers(10万リクエスト/日)Serverless FunctionsFunctions
カスタムドメイン
SSL◎(自動)◎(自動)◎(自動)
プレビューデプロイ
Web Analytics◎(無料)有料有料

選び方の目安

Cloudflare Pages が向いている場合(Vercelの代替サービスについては「[Vercel代替サービス比較](/blog/vercel-alternatives-free-hosting/)」も参照):
  - 帯域を気にせず運用したい
  - 静的サイト / Astro / Next.js のSSG
  - Cloudflare のエコシステム(DNS、R2、KV)を活用したい
  - Web Analytics を無料で使いたい

Vercel が向いている場合:
  - Next.js を使う(最適化が手厚い)
  - SSR / ISR を多用する
  - Edge Functions のパフォーマンスを重視

Netlify が向いている場合:
  - フォーム機能(Netlify Forms)を使いたい
  - Identity(認証)機能を使いたい
  - CMS との連携が多い

プロジェクト作成手順

方法1: Cloudflare ダッシュボードから(GUI)

1. Cloudflare ダッシュボードにログイン
2. Workers & Pages → Create → Pages → Connect to Git
3. GitHub / GitLab アカウントを連携
4. リポジトリを選択
5. ビルド設定を入力:
   - フレームワーク: Astro(自動検出される場合もあり)
   - ビルドコマンド: npm run build
   - ビルド出力ディレクトリ: dist
6. 「Save and Deploy」をクリック

方法2: Wrangler CLI から(推奨)

# Wrangler のインストール
npm install -g wrangler

# Cloudflare にログイン
wrangler login

# プロジェクトの作成&デプロイ
wrangler pages deploy dist --project-name my-site

# GitHub 連携でのプロジェクト作成
wrangler pages project create my-site

フレームワーク別のビルド設定

フレームワークビルドコマンド出力ディレクトリ
Astronpm run builddist
Next.jsnpx @cloudflare/next-on-pages.vercel/output/static
Nuxtnpm run build.output/public
SvelteKitnpm run build.svelte-kit/cloudflare
Remixnpm run buildbuild/client
Vite (React/Vue)npm run builddist
Hugohugopublic

Astroでブログサイトを構築する方法は「Astroブログチュートリアル」で詳しく解説しています。

Astro プロジェクトの設定例(当サイトの実例)

// astro.config.mjs
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'static', // SSG の場合
  // output: 'server', // SSR の場合は Cloudflare アダプター必要
  site: 'https://toolcraftlab.dev',
  build: {
    assets: '_assets',
  },
  vite: {
    build: {
      cssMinify: true,
    },
  },
});

カスタムドメインの設定

Cloudflare DNS を使う場合(最速)

Cloudflare にドメインのネームサーバーを向けている場合、設定は非常に簡単です。

1. Workers & Pages → 対象プロジェクト → Custom domains
2. 「Set up a custom domain」をクリック
3. ドメイン名を入力(例: toolcraftlab.dev)
4. DNS レコードが自動的に追加される
5. SSL 証明書も自動発行(通常数分以内)

外部 DNS を使う場合

1. Custom domains でドメインを追加
2. 表示される CNAME レコードを外部 DNS に設定:
   - Type: CNAME
   - Name: @ または サブドメイン
   - Target: your-project.pages.dev
3. SSL 証明書の発行を待つ(最大24時間)

www リダイレクトの設定

# _redirects ファイル(プロジェクトルートに配置)
https://www.toolcraftlab.dev/* https://toolcraftlab.dev/:splat 301

Cloudflare Functions(サーバーレスAPI)

Cloudflare Pages Functions は、Cloudflare Workers をベースにしたサーバーレス関数です。functions/ ディレクトリにファイルを置くだけで自動的にAPIエンドポイントが生成されます。

ディレクトリ構造

project/
├── src/           # フロントエンドのソースコード
├── functions/     # サーバーレス関数
│   ├── api/
│   │   ├── hello.js          # → /api/hello
│   │   ├── users/
│   │   │   ├── index.js      # → /api/users
│   │   │   └── [id].js       # → /api/users/:id
│   │   └── [...catchall].js  # → /api/*
│   └── _middleware.js         # 全ルートに適用
├── public/
└── dist/

基本的な Functions の例

// functions/api/hello.js
export async function onRequestGet(context) {
  return new Response(JSON.stringify({
    message: "Hello from Cloudflare Pages Functions!",
    timestamp: new Date().toISOString(),
  }), {
    headers: {
      "Content-Type": "application/json",
    },
  });
}

export async function onRequestPost(context) {
  const body = await context.request.json();
  // POST リクエストの処理
  return new Response(JSON.stringify({
    received: body,
  }), {
    headers: {
      "Content-Type": "application/json",
    },
  });
}

環境変数の利用

// functions/api/secure.js
export async function onRequestGet(context) {
  // 環境変数はコンテキストから取得
  const apiKey = context.env.API_KEY;

  if (!apiKey) {
    return new Response("API key not configured", { status: 500 });
  }

  // 外部 API を呼び出す例
  const response = await fetch("https://api.example.com/data", {
    headers: {
      "Authorization": `Bearer ${apiKey}`,
    },
  });

  const data = await response.json();
  return new Response(JSON.stringify(data), {
    headers: { "Content-Type": "application/json" },
  });
}
# 環境変数の設定(CLI)
wrangler pages secret put API_KEY
# プロンプトでシークレットの値を入力

# または ダッシュボードから
# Workers & Pages → 対象プロジェクト → Settings → Environment variables

ミドルウェアの活用

// functions/_middleware.js
export async function onRequest(context) {
  // CORS ヘッダーの追加
  const response = await context.next();
  response.headers.set("Access-Control-Allow-Origin", "*");
  response.headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
  response.headers.set("Access-Control-Allow-Headers", "Content-Type");
  return response;
}

Cloudflare Pages の周辺サービス連携

R2(オブジェクトストレージ)

画像や大きなファイルの配信に使えます。S3互換で、エグレス料金が無料です。

// functions/api/upload.js
export async function onRequestPost(context) {
  const formData = await context.request.formData();
  const file = formData.get("file");

  if (!file) {
    return new Response("No file provided", { status: 400 });
  }

  // R2 にファイルをアップロード
  await context.env.MY_BUCKET.put(file.name, file.stream(), {
    httpMetadata: {
      contentType: file.type,
    },
  });

  return new Response(JSON.stringify({
    message: "Uploaded successfully",
    filename: file.name,
  }));
}

KV(キーバリューストア)

設定値やキャッシュデータの保存に便利です。

// functions/api/config.js
export async function onRequestGet(context) {
  const value = await context.env.MY_KV.get("site-config");
  return new Response(value, {
    headers: { "Content-Type": "application/json" },
  });
}

Web Analytics

Cloudflare Pages には無料の Web Analytics が付属しています。

設定方法:
1. ダッシュボード → Web Analytics
2. サイトを追加
3. 自動的にビーコンスクリプトが挿入される(Pages の場合)
   または手動でスクリプトタグを追加

実際の運用 Tips(当サイトの経験から)

1. ビルドキャッシュの活用

# wrangler.toml
[build]
command = "npm run build"
cwd = "."

[build.environment]
NODE_VERSION = "20"

2. _headers ファイルでセキュリティヘッダーを設定

# public/_headers
/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()
  X-XSS-Protection: 1; mode=block

/assets/*
  Cache-Control: public, max-age=31536000, immutable

/*.html
  Cache-Control: public, max-age=0, must-revalidate

3. _redirects ファイルでリダイレクト管理

# public/_redirects
# www → non-www
https://www.toolcraftlab.dev/* https://toolcraftlab.dev/:splat 301

# 旧URL → 新URL
/old-path /new-path 301

# 外部リダイレクト
/github https://github.com/your-org 302

4. デプロイ通知の設定

# GitHub Actions でデプロイ後に通知する例
# .github/workflows/deploy-notify.yml
name: Deploy Notification
on:
  deployment_status:

jobs:
  notify:
    if: github.event.deployment_status.state == 'success'
    runs-on: ubuntu-latest
    steps:
      - name: Notify Discord
        uses: sarisia/actions-status-discord@v1
        with:
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          title: "Deploy Success"
          description: "New version deployed to Cloudflare Pages"

5. ビルド回数の節約

無料プランでは月500回のビルド制限があります。

# 節約のコツ
- README や docs の変更ではビルドをスキップ
  → コミットメッセージに [skip ci] を含める
- main ブランチのみ本番デプロイに設定
- プレビューデプロイの対象ブランチを制限
# [skip ci] の使い方
git commit -m "docs: READMEを更新 [skip ci]"

トラブルシューティング

よくある問題と対策

問題原因対策
ビルドが失敗するNode.js バージョンの不一致環境変数 NODE_VERSION=20 を設定
404 が表示されるSPA のルーティング_redirects/* /index.html 200 を設定
画像が表示されないファイルサイズ超過25MB以下に圧縮、またはR2を使用
Functions が動かないディレクトリ名の間違いfunctions/ が正しい位置にあるか確認
SSL エラーDNS 設定の反映待ち最大24時間待つ、Cloudflare DNS なら数分

ビルドログの確認

1. ダッシュボード → Workers & Pages → 対象プロジェクト
2. Deployments タブ
3. 対象のデプロイをクリック
4. Build log でエラーの詳細を確認

まとめ — Cloudflare Pages は個人開発者の最強ホスティング

Cloudflare Pages は、特に以下の点で個人開発者やインディーデベロッパーにとって最適な選択肢です。

  1. 帯域無制限・無料: トラフィックが増えても課金されない安心感
  2. グローバルCDN: 日本からのアクセスも高速
  3. Cloudflare エコシステム: DNS、R2、KV、Analytics が統合されている
  4. Functions: 簡単なAPI機能も無料で追加可能
  5. プレビューデプロイ: PR レビューが効率化される

当サイト(toolcraftlab.dev)も Cloudflare Pages で運用しており、コストゼロで安定したパフォーマンスを実現しています。無料プランの制限もほとんど気になりません。

まずは試しに一つプロジェクトをデプロイしてみてください。GitHub リポジトリの連携から本番公開まで、10分もかかりません。