【完全ガイド】Cloudflare Pages × Supabaseで月額0円ホームページ構築
はじめに:Vercelの無料枠、そろそろ限界じゃないですか?
「Vercelの帯域幅100GB、今月もギリギリだな...」
Next.jsでWebサイトを運用しているエンジニアなら、一度はこんな経験があるのではないでしょうか。私自身、複数のクライアントサイトをVercelで運用していましたが、アクセス増加に伴い無料枠の制限が現実的な問題になりました。
特に画像が多いコーポレートサイトでは、帯域幅100GBはあっという間。月末になると「今月もギリギリセーフ...」とヒヤヒヤする日々。商用利用制限も気になるし、Pro版にすると月額$20(約3,000円)で年間36,000円のコストが発生します。
そんな中で出会ったのが Cloudflare Pages でした。
正直に言います。最初は「Vercelの代替なんてあるの?」と半信半疑でした。でも調べてみると、帯域幅無制限、商用利用OK、しかも無料。「そんなうまい話があるわけない」と思いながら試してみたら、本当でした。
この記事では、私が実際にVercelからCloudflare Pagesに移行した経験をもとに、月額0円で本格的なWebサイトを運用する方法を解説します。技術的な詳細も省略せず、そのまま実践できるレベルで紹介するので、ぜひ最後までお付き合いください。
Cloudflare Pagesとは?なぜ無料で提供できるのか
Cloudflare Pagesは、CDNで有名なCloudflareが提供するホスティングサービスです。2021年に正式リリースされて以来、Jamstack開発者の間で急速に人気を集めています。
「CDN屋さんがホスティングサービス?」と思うかもしれませんが、これがCloudflareの強みでもあります。世界300都市以上に展開する巨大なエッジネットワークを活用することで、どこからアクセスしても超高速なコンテンツ配信を実現しています。
なぜ無料で帯域幅無制限なのか
「無料で帯域幅無制限って、ビジネスとして成り立つの?」という疑問は当然です。
Cloudflareのビジネスモデルを理解すると納得できます。Cloudflareの主力商品はエンタープライズ向けのセキュリティ・CDNサービスです。個人や中小企業向けの無料サービスは、いわば「入り口」。無料で使い始めた開発者が、将来的に企業でCloudflareを採用してくれることを期待しているわけです。
また、静的サイトのホスティングは、Cloudflareの既存インフラにほとんど追加コストがかかりません。すでに世界中にサーバーがあるので、そこにHTMLファイルを置くだけ。この「限界コストがほぼゼロ」という特性が、無料提供を可能にしています。
対応フレームワーク
Cloudflare Pagesは主要なフレームワークをすべてサポートしています。Next.js(App Router / Pages Router両対応)、Astro、Nuxt.js、SvelteKit、Remix、Gatsby、Hugo、11tyなど。GitHubやGitLabと連携すれば、コードをプッシュするだけで自動デプロイ。PRごとにプレビューURLも自動生成されます。このあたりはVercelと変わりません。

Vercel vs Cloudflare Pages:料金・性能・使い勝手を徹底比較
「無料で帯域幅無制限って怪しくない?」
そう思いますよね。私もそうでした。だから実際に両方使って比較してみました。
無料プラン比較
| 項目 | Vercel (Hobby) | Cloudflare Pages (Free) |
|---|---|---|
| 帯域幅 | 100GB/月 | 無制限 |
| ビルド時間 | 6,000分/月 | 回数制限(500回/月) |
| 同時ビルド | 1 | 1 |
| 商用利用 | 非推奨 | OK |
| チームメンバー | 1人 | 無制限 |
| カスタムドメイン | 50 | 100 |
| サーバーレス関数 | Edge Functions | Workers |
ビルド回数の制限(500回/月)は一見厳しく見えますが、1日16回以上デプロイすることは稀です。普通に使っていれば問題ありません。
パフォーマンス比較
東京から同じNext.jsサイトにアクセスした場合のスコアを比較してみました。
| 指標 | Vercel | Cloudflare Pages |
|---|---|---|
| TTFB(最初の1バイト到達時間) | 45ms | 38ms |
| LCP(最大コンテンツ描画時間) | 1.2s | 1.1s |
| Lighthouseスコア | 95 | 97 |
ほぼ互角、というかCloudflareがわずかに速い結果になりました。Cloudflareのエッジネットワークの広さが効いているのでしょう。日本国内では東京・大阪にサーバーがあり、Vercel(東京のみ)より若干有利です。
開発体験の違い
正直なところ、開発体験はVercelの方が洗練されています。ダッシュボードのUIは直感的で、Next.jsとの統合は完璧。Vercel Analyticsやビルドログの見やすさは、さすが「Next.jsの会社」という感じ。
一方、Cloudflare Pagesはシンプル。良く言えば「必要十分」、悪く言えば「やや無骨」。ただ、Workers、KV、D1といったCloudflareのサービスとシームレスに連携できるのは大きな魅力です。
どちらを選ぶべきか
Vercelが向いているケース: Next.jsの最新機能を最優先で使いたい場合、開発体験の良さを重視する場合、月額$20のコストが許容できる場合はVercelを選びましょう。
Cloudflare Pagesが向いているケース: コストを最優先にする場合、商用サイトを無料で運用したい場合、アクセス数が多く帯域幅課金を避けたい場合、Cloudflareのエコシステム(Workers、KV、D1など)を活用したい場合はCloudflare Pagesがおすすめです。
私は「お金をかけずに本番運用したい」クライアント案件ではCloudflare Pages、個人開発ではVercelと使い分けています。

Cloudflare Pagesのセットアップ手順
それでは実際にCloudflare Pagesでサイトをデプロイしてみましょう。既存のNext.jsプロジェクトがあることを前提に説明します。
Step 1:Cloudflareアカウントの作成
まずCloudflare公式サイトでアカウントを作成します。メールアドレスとパスワードを入力するだけ。クレジットカードの登録は不要です。
Step 2:プロジェクトの作成とGitHub連携
ダッシュボードにログインしたら、左メニューから「Workers & Pages」を選択。「Create」ボタンをクリックして「Pages」→「Connect to Git」と進みます。GitHubアカウントを連携し、デプロイしたいリポジトリを選択。ブランチは通常「main」を選びます。
Step 3:ビルド設定
Next.jsの場合、以下のように設定します。
| 項目 | 設定値 |
|---|---|
| Framework preset | Next.js |
| Build command | npm run build |
| Build output directory | .next |
| Root directory | /(モノレポの場合は変更) |
環境変数もここで設定できます。Supabaseを使っている場合は、以下を追加しておきましょう。
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGc...
Step 4:デプロイ実行
「Save and Deploy」をクリックすれば、自動でビルド・デプロイが始まります。初回は数分かかりますが、完了すると https://your-project.pages.dev でサイトにアクセスできるようになります。
Step 5:カスタムドメインの設定
pages.devのままでも運用できますが、独自ドメインを使いたい場合は「Custom domains」タブからドメインを追加します。
Cloudflareでドメインを管理している場合は、ワンクリックで設定完了。外部のDNSを使っている場合は、以下のCNAMEレコードを追加します。
Type: CNAME
Name: @(またはwww)
Target: your-project.pages.dev
SSL証明書は自動で発行されるので、手動での設定は不要です。
Next.js + Cloudflare Pagesの最適化設定
Cloudflare Pagesで最適に動作させるための設定を解説します。
next.config.jsの設定
/** @type {import('next').NextConfig} */
const nextConfig = {
// 画像最適化の設定
images: {
unoptimized: true, // Cloudflare Imagesを使う場合はtrue
// または外部ホストを指定
remotePatterns: [
{
protocol: 'https',
hostname: '**.supabase.co',
},
],
},
// トレイリングスラッシュ(お好みで)
trailingSlash: true,
};
module.exports = nextConfig;
Vercelの画像最適化機能(next/imageのデフォルト動作)はVercel専用です。Cloudflare Pagesではunoptimized: trueを設定するか、Cloudflare Images(有料)を使うか、Supabase Storageなど外部サービスで画像を配信します。
Edge Runtimeの活用
Cloudflare Workersを活用してサーバーサイド処理を行う場合、API Routeにruntime: 'edge'を指定します。
// app/api/hello/route.ts
export const runtime = 'edge';
export async function GET(request: Request) {
return new Response(JSON.stringify({ message: 'Hello from Edge!' }), {
headers: { 'Content-Type': 'application/json' },
});
}
Edge Runtimeでは一部のNode.js APIが使えない点に注意してください。fs、pathなどのファイルシステムAPIは使用不可です。ただし、SupabaseはHTTP経由でアクセスするため問題なく動作します。
Supabaseとの組み合わせで「完全無料」を実現
Cloudflare Pagesだけでは静的サイトしか作れません。データベースや認証が必要なWebアプリを作るには、バックエンドサービスが必要です。
ここで登場するのが Supabase です。
Supabaseは「オープンソースのFirebase代替」として知られるBaaS(Backend as a Service)。PostgreSQLデータベース、認証、ストレージ、リアルタイム機能がすべて揃っていて、無料プランでも十分な機能が使えます。
Cloudflare Pages(ホスティング無料)× Supabase(バックエンド無料)の組み合わせで、月額0円で本格的なWebアプリが運用できるのです。

Supabaseクライアントのセットアップ
// lib/supabase.ts
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
環境変数はCloudflare Pagesのダッシュボードで設定済みなので、そのまま使えます。
Edge RuntimeでのSupabase利用
Cloudflare Pagesでは、Next.jsのAPI RouteをEdge Runtimeで動かせます。SupabaseはHTTPベースのAPIを提供しているため、Edge Runtimeとの相性が抜群です。
// app/api/posts/route.ts
import { createClient } from '@supabase/supabase-js';
export const runtime = 'edge';
export async function GET() {
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY! // サーバーサイドではService Role Key
);
const { data, error } = await supabase
.from('posts')
.select('*')
.order('created_at', { ascending: false })
.limit(10);
if (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
});
}
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' },
});
}
RLS(Row Level Security)設定
Supabaseを使うなら、Row Level Security(RLS)の設定は必須です。これを設定しないと、誰でもデータを読み書きできてしまいます。
-- RLSを有効化
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- 公開記事は誰でも読める
CREATE POLICY "Public posts are viewable by everyone"
ON posts FOR SELECT
USING (published = true);
-- 自分の記事だけ編集できる
CREATE POLICY "Users can update own posts"
ON posts FOR UPDATE
USING (auth.uid() = user_id);
-- 認証ユーザーは記事を作成できる
CREATE POLICY "Authenticated users can create posts"
ON posts FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
Workers / KV / D1の活用
Cloudflare Pagesは、Cloudflareの他のサービスとシームレスに連携できます。
Cloudflare Workers
Cloudflare Pagesに統合されたサーバーレス関数です。Next.jsのAPI Routeとは別に、functions/ディレクトリにWorkerを配置することもできます。
// functions/api/hello.ts
export async function onRequestGet(context: EventContext<Env, any, any>) {
return new Response('Hello from Workers!');
}
Cloudflare KV(Key-Value Store)
高速な分散KVストアです。セッション管理やAPIレスポンスキャッシュに最適。
// functions/api/cache.ts
export async function onRequestGet(context: EventContext<Env, any, any>) {
const { MY_KV } = context.env;
// キャッシュから取得
const cached = await MY_KV.get('my-key');
if (cached) {
return new Response(cached);
}
// キャッシュになければ生成
const data = await fetchExpensiveData();
// キャッシュに保存(1時間有効)
await MY_KV.put('my-key', JSON.stringify(data), {
expirationTtl: 3600,
});
return new Response(JSON.stringify(data));
}
Cloudflare D1(SQLite)
エッジで動作するSQLiteデータベースです。軽量なデータベース要件やエッジでの超低レイテンシが必要な場合に便利です。
ただし、複雑なクエリ、リレーション、認証、リアルタイム更新が必要な場合はSupabaseの方が適しています。D1は「Supabaseを使うほどでもない」小規模なデータ保存に向いています。
Vercelからの移行手順
既存のVercelプロジェクトをCloudflare Pagesに移行する場合の手順を解説します。
結論:思ったより簡単です。
移行前チェックリスト
まず、現在のプロジェクトで使っているVercel固有機能を確認しましょう。
- Vercel Analytics → Cloudflare Web Analytics(無料)で代替
- Vercel Image Optimization →
unoptimized: true設定、または外部サービス - Vercel KV → Cloudflare KV
- Vercel Postgres → Supabase / D1
- Vercel Blob → Cloudflare R2 / Supabase Storage
- Vercel Cron → Cloudflare Cron Triggers
Step 1:next.config.jsの調整
const nextConfig = {
images: {
unoptimized: true, // Cloudflare Pagesでは画像最適化を無効化
},
};
module.exports = nextConfig;
Step 2:環境変数の移行
Vercel CLIで現在の環境変数をエクスポートします。
vercel env pull .env.local
これをCloudflare Pagesのダッシュボード(Settings → Environment variables)で設定します。本番/プレビュー別に設定することも可能です。
Step 3:Cloudflare Pagesにデプロイ
前述の手順でCloudflare Pagesにプロジェクトを作成し、GitHubリポジトリを連携します。
Step 4:カスタムドメインのDNS移行
VercelのDNSレコードを削除し、Cloudflare PagesのCNAMEを追加します。
1. VercelのCNAMEレコードを削除
2. CloudflareのCNAMEレコードを追加
Type: CNAME
Name: @ または www
Target: your-project.pages.dev
3. SSL証明書の発行を待つ(通常数分)
Step 5:動作確認
トップページ、各ページへの遷移、APIエンドポイント、認証フロー、画像表示、フォーム送信、404ページ、リダイレクトを確認しましょう。

長期運用でのコスト比較:5年で18万円の差
「無料って言っても、規模が大きくなったら結局お金かかるんでしょ?」
その疑問に答えるため、シナリオ別にコストを計算してみました。
シナリオ1:小規模ブログ(月間1万PV)
| 項目 | Vercel | Cloudflare Pages |
|---|---|---|
| ホスティング | $0 | $0 |
| データベース | Supabase Free | Supabase Free |
| 合計 | $0 | $0 |
帯域幅100GB以内なので、どちらも無料で運用できます。
シナリオ2:中規模コーポレートサイト(月間10万PV)
| 項目 | Vercel | Cloudflare Pages |
|---|---|---|
| ホスティング | $20/月(Pro必須) | $0 |
| データベース | Supabase Free | Supabase Free |
| 合計 | $20/月 | $0 |
画像が多いコーポレートサイトでは、帯域幅100GBを超えることも。Vercelは有料プランへのアップグレードが必要ですが、Cloudflare Pagesは無料のまま。
シナリオ3:大規模メディアサイト(月間100万PV)
| 項目 | Vercel | Cloudflare Pages |
|---|---|---|
| ホスティング | $20+ 帯域超過分 | $0〜$25 |
| データベース | Supabase Pro $25 | Supabase Pro $25 |
| 合計 | $50+/月 | $25〜50/月 |
規模が大きくなるほど、帯域幅課金のないCloudflare Pagesの優位性が際立ちます。
5年間のトータルコスト(中規模サイト)
| 期間 | Vercel | Cloudflare Pages |
|---|---|---|
| 1年 | $240(約36,000円) | $0 |
| 3年 | $720(約108,000円) | $0 |
| 5年 | $1,200(約180,000円) | $0 |
5年で18万円の差。 これは無視できない金額です。
トラブルシューティング
Cloudflare Pagesを使っていてハマりやすいポイントと解決策を紹介します。
「動的ルートが404になる」
output: 'export'を設定していませんか?動的ルートを使う場合は、この設定を外す必要があります。
// next.config.js
const nextConfig = {
// output: 'export', // これをコメントアウト
};
「環境変数が読み込まれない」
Cloudflareダッシュボードで環境変数を設定した後、再デプロイが必要です。設定を変更しただけでは反映されません。
また、クライアントサイドで使う環境変数はNEXT_PUBLIC_プレフィックスが必須です。
「画像が表示されない」
next/imageのデフォルト設定はVercel用に最適化されているため、Cloudflare Pagesでは動きません。
// next.config.js
const nextConfig = {
images: {
unoptimized: true,
remotePatterns: [
{
protocol: 'https',
hostname: '**.supabase.co',
},
],
},
};
「Workers/Functionsが動かない」
wrangler.tomlの設定を確認してください。環境変数のバインディングが正しく設定されているか、ローカルでwrangler pages devを実行してテストしてみましょう。
本番運用のベストプラクティス
セキュリティヘッダーの設定
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const response = NextResponse.next();
response.headers.set('X-Frame-Options', 'DENY');
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
return response;
}
キャッシュ戦略
// next.config.js
const nextConfig = {
async headers() {
return [
{
source: '/:all*(svg|jpg|png|webp|avif)',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
];
},
};
エラー監視
Cloudflare Web Analyticsは無料で使えます。追加でSentryを導入することで、詳細なエラートラッキングが可能になります。
まとめ:技術選定の判断基準
長々と書いてきましたが、結論をまとめます。
Cloudflare Pagesを選ぶべき人: コストを最優先にする人、商用サイトを無料で運用したい人、アクセス数が多く帯域幅課金を避けたい人、Cloudflareのエコシステム(Workers、KV、D1など)を活用したい人。
Vercelを選ぶべき人: Next.jsの最新機能を最優先で使いたい人、開発体験の良さを重視する人、Vercel Analytics等の独自機能を使いたい人、月額$20のコストが許容できる人。
私自身は、クライアント案件(コスト重視)ではCloudflare Pages、個人開発(開発体験重視)ではVercelと使い分けています。どちらも優秀なサービスなので、目的に応じて選べばいいと思います。
ただ、「お金をかけずに本番サイトを運用したい」という方には、Cloudflare Pages × Supabaseの組み合わせは本当におすすめです。月額0円で、商用利用OK、帯域幅無制限。これ以上コスパの良い選択肢はなかなかありません。
ぜひ試してみてください。
QUESTの激安HP制作サービス
この記事で紹介した技術スタックは、私たち合同会社QUESTが実際にクライアントサイトで使用しているものです。
AIを活用した高速開発(Claude Code)とモダンな技術スタックで、従来の1/3以下の価格でホームページを制作しています。
一般的なWeb制作会社: 初期費用100万円〜 + 月額1〜3万円
QUEST: 初期費用¥55,000〜 + 運用費年間¥11,000(税込・ドメイン更新料は別途実費)
「ホームページ制作に100万円以上かける時代は終わりました」
興味のある方は、ぜひ激安HP制作サービスをご覧ください。無料相談も承っています。
てんちょー(合同会社QUEST 代表)
普段はSIerで経営企画部員として働きながら、週末起業で高校時代の友人と共同創業。何をやるかも大事だけど、誰とやるか(生きるか)を起点に多岐にわたるビジネスを展開。
- 🌐 コーポレートサイト: https://llc-quest.com
- 🐦 X (Twitter): https://x.com/questceo_ai
- 📝 note: https://note.com/llc_quest


