Cloudflare R2 は S3 互換のオブジェクトストレージで、最大の特徴はエグレス(データ転送)料金がゼロであることです。大量の画像を配信するアプリケーションでは、この差が大きなコスト削減につながります。
R2 の特徴
- エグレス料金ゼロ(S3 は高額なエグレス料金がかかる)
- S3 互換 API が使えるため既存ツールと統合しやすい
- Cloudflare Workers/Pages から直接バインディングでアクセス可能
- カスタムドメインと Cloudflare CDN で高速配信
- Wrangler でローカルエミュレーション可能
wrangler.toml の設定
toml
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-images"画像アップロード API の実装
Next.js の API Route から FormData で受け取ったファイルを R2 に PUT します。Edge Runtime で動作させるために export const runtime = "edge" の宣言が必要です。
typescript
import { getRequestContext } from "@cloudflare/next-on-pages";
import { NextRequest, NextResponse } from "next/server";
export const runtime = "edge";
export async function POST(request: NextRequest) {
const { env } = getRequestContext();
const formData = await request.formData();
const file = formData.get("file") as File;
const key = `uploads/${Date.now()}-${file.name}`;
await env.BUCKET.put(key, await file.arrayBuffer(), {
httpMetadata: { contentType: file.type },
});
return NextResponse.json({ ok: true, key });
}画像配信のパターン
ローカルエミュレーション環境では R2 バケットへの公開 URL が使えないため、取得用の API Route を用意する方法が簡単です。本番では R2 バケットにカスタムドメインを設定し、Cloudflare CDN 経由で直接配信するのが最もパフォーマンスが高いパターンです。
ローカルでの確認方法
wrangler pages dev または next dev + setupDevPlatform() を使うと、.wrangler/state/v3/r2/ 以下にファイルがエミュレートされます。アップロードした内容を確認するには、別途 GET エンドポイントを作成して BUCKET.get(key) で取得します。