Cloudflare Pages のデプロイメントガイド。Pages Functions、フレームワーク対応(Next.js, Nuxt, Astro, SvelteKit, Remix, Hono)、ビルド設定、プレビュー環境について提供。Use when user asks about Pages deployment, Pages Functions, framework support, Next.js, Nuxt, Astro, SvelteKit, Remix, or Hono on Cloudflare. Also use when user says Pages デプロイ, フレームワーク, SSR, 静的サイト.
Provides Cloudflare Pages deployment guidance for frameworks and Functions.
/plugin marketplace add biwakonbu/cc-plugins/plugin install biwakonbu-cloudflare-knowledge-plugins-cloudflare-knowledge@biwakonbu/cc-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Cloudflare Pages は静的サイトとフルスタックアプリケーションのホスティングプラットフォーム。 Git 連携による自動デプロイ、Pages Functions(Workers 統合)、プレビュー環境を提供。
2025年現在、Pages と Workers の境界は事実上消滅し、フルスタックエッジアプリとして統合。
# 静的サイトをデプロイ
npx wrangler pages deploy ./dist
# プロジェクト名指定
npx wrangler pages deploy ./dist --project-name my-site
# ブランチ指定(プレビュー)
npx wrangler pages deploy ./dist --branch preview
Cloudflare ダッシュボードで GitHub/GitLab を接続:
project/
├── functions/ # Functions ディレクトリ(必須)
│ ├── index.ts # → /
│ ├── hello.ts # → /hello
│ ├── api/
│ │ ├── data.ts # → /api/data
│ │ └── users/
│ │ └── [id].ts # → /api/users/:id
│ ├── _middleware.ts # ミドルウェア
│ └── [[path]].ts # キャッチオール
└── public/ # 静的アセット
| パターン | ファイル | マッチ |
|---|---|---|
| 静的 | functions/hello.ts | /hello |
| 動的 | functions/posts/[id].ts | /posts/123 |
| キャッチオール | functions/api/[[path]].ts | /api/a/b/c |
// functions/api/users/[id].ts
export const onRequestGet: PagesFunction<Env> = async (context) => {
const userId = context.params.id;
const user = await context.env.DB.prepare(
"SELECT * FROM users WHERE id = ?"
).bind(userId).first();
if (!user) {
return new Response("Not found", { status: 404 });
}
return Response.json(user);
};
export const onRequestPost: PagesFunction<Env> = async (context) => {
const body = await context.request.json();
// ...
return Response.json({ success: true });
};
// 全メソッド対応
export const onRequest: PagesFunction<Env> = async (context) => {
return new Response(`Method: ${context.request.method}`);
};
// functions/_middleware.ts
export const onRequest: PagesFunction<Env> = async (context) => {
// 認証チェック
const auth = context.request.headers.get("Authorization");
if (!auth && context.request.url.includes("/api/")) {
return new Response("Unauthorized", { status: 401 });
}
// 次のハンドラーへ
const response = await context.next();
// レスポンス加工
response.headers.set("X-Custom-Header", "value");
return response;
};
interface EventContext<Env> {
request: Request;
env: Env;
params: Record<string, string>;
waitUntil(promise: Promise<unknown>): void;
passThroughOnException(): void;
next(): Promise<Response>;
data: Record<string, unknown>; // ミドルウェア間でデータ共有
}
| フレームワーク | 方式 | SSR | ISR | 備考 |
|---|---|---|---|---|
| Next.js | OpenNext + Workers | ○ | ○ | App Router 完全対応 |
| Nuxt 3 | Pages 直接 | ○ | ○ | Nitro プリセット |
| Astro | @astrojs/cloudflare | ○ | - | アダプター必須 |
| SvelteKit | @sveltejs/adapter-cloudflare | ○ | - | |
| Remix | Pages 直接 | ○ | - | エッジネイティブ |
| Hono | Workers/Pages | ○ | - | 最も親和性高 |
2025年推奨: OpenNext + Cloudflare Workers
# プロジェクト作成
npm create cloudflare@latest my-next-app -- --framework=next
# ビルド
npx open-next@cloudflare build
# デプロイ
npx wrangler deploy
対応機能:
ゼロ設定でデプロイ可能:
# ビルド(SSR)
nuxt build
# ビルド(静的)
nuxt generate
# デプロイ
npx wrangler pages deploy .output/public
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: "cloudflare-pages",
},
});
# アダプター追加
npx astro add cloudflare
// astro.config.mjs
import cloudflare from "@astrojs/cloudflare";
export default defineConfig({
output: "server", // または "hybrid"
adapter: cloudflare(),
});
# アダプター追加
npm install -D @sveltejs/adapter-cloudflare
// svelte.config.js
import adapter from "@sveltejs/adapter-cloudflare";
export default {
kit: {
adapter: adapter(),
},
};
# テンプレートから作成
npx create-cloudflare@latest my-remix-app -- --framework=remix
最も Cloudflare に最適化されたフレームワーク:
npm create cloudflare@latest my-app -- --template hono
import { Hono } from "hono";
const app = new Hono();
app.get("/", (c) => c.text("Hello Hono!"));
app.get("/api/users/:id", async (c) => {
const id = c.req.param("id");
const user = await c.env.DB.prepare(
"SELECT * FROM users WHERE id = ?"
).bind(id).first();
return c.json(user);
});
export default app;
#:schema node_modules/wrangler/config-schema.json
name = "my-pages-app"
compatibility_date = "2025-01-01"
# ビルド出力ディレクトリ
pages_build_output_dir = "dist"
# 環境変数
[vars]
API_URL = "https://api.example.com"
# D1
[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "xxx"
# KV
[[kv_namespaces]]
binding = "KV"
id = "xxx"
# R2
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-bucket"
[env.preview]
vars = { API_URL = "https://staging-api.example.com" }
[env.production]
vars = { API_URL = "https://api.example.com" }
https://<hash>.<project>.pages.dev# 特定ブランチとしてデプロイ
npx wrangler pages deploy ./dist --branch feature-x
Cloudflare Access でプレビュー URL を保護可能。
| 設定 | 例 |
|---|---|
| ビルドコマンド | npm run build |
| ビルド出力ディレクトリ | dist / .next / .output/public |
| ルートディレクトリ | / または apps/web |
| 場所 | 用途 |
|---|---|
| ダッシュボード | 本番シークレット |
.dev.vars | ローカル開発 |
wrangler.toml の [vars] | 非機密設定 |
| 変数 | 説明 |
|---|---|
CF_PAGES | Pages ビルドかどうか |
CF_PAGES_BRANCH | ブランチ名 |
CF_PAGES_COMMIT_SHA | コミットハッシュ |
CF_PAGES_URL | デプロイ URL |
Pages Functions のルーティングが不十分な場合、_worker.js を直接配置:
// dist/_worker.js
export default {
async fetch(request, env) {
const url = new URL(request.url);
// 静的アセット
if (url.pathname.startsWith("/assets/")) {
return env.ASSETS.fetch(request);
}
// API
if (url.pathname.startsWith("/api/")) {
return handleApi(request, env);
}
// SPA フォールバック
return env.ASSETS.fetch(new Request(
new URL("/index.html", request.url),
request
));
},
};
外部 DNS の場合:
CNAME www <project>.pages.dev
| 項目 | 制限 |
|---|---|
| ビルド時間 | 20分(Free)/ 30分(Pro) |
| ファイルサイズ | 25MB/ファイル |
| ファイル数 | 20,000ファイル |
| Functions | Workers と同じ制限 |
| ビルド数 | 500/月(Free)/ 5000/月(Pro) |