Cloudflare:Workers
2026年4月14日npm create cloudflare@latestランタイム
Cloudflare WorkersはEdgeランタイム。
Nodejsランタイムが前提のようなライブラリが多いため、Workersでは調べて対策しないと機能しない事が多い。
Nodejsランタイムはプロセスとして起動する(サーバーレスの場合もプロセスはしばらく残る)が、Edgeランタイムは共有プロセス内の一部( = Isolate上)でコードが実行される。
EdgeランタイムではPrismaやfsが使えない。HTTP接続だとDBにアクセスできる。(例:NeonやUpstash Redis)
Pages
*「Workersを推奨」と公式サイトに書かれている
用途:
静的ページが多いサイト
非同期処理を行う各ファイルに以下を追加しないとエラーになる
export const runtime = 'edge';NextjsをCloudflareのランタイムで実行させる為には、Workersダッシュボードから
settings/Compatibility flagsに移動し、nodejs_compatと書いてEnter
Workers
用途:
Vercelと似た感じでアプリをサーバーレスでデプロイすることができる
Node.js前提のライブラリは機能しないことがあるので調べて対応
workers.devドメインはアカウント名がドメインに入ってしまう。
Nextjs
NextjsはNode.jsが前提となっているのでNode.jsランタイムではないWorkersではそのままだと動かない。
OpenNext:https://opennext.js.org/
OpenNextはNext.jsのビルド結果をNode.js以外の実行環境でも動くように
構成し直す
npm create cloudflare@latest -- my-next-app --framework=nextテンプレートで作成したアプリは初回デプロイ時にビルドエラーになるので、Cloudflareの設定からビルドコマンドを
npm run buildから以下に変更
npx opennextjs-cloudflare build環境変数
「Workersダッシュボード/変数とシークレット」から環境変数を追加、またはターミナルから
npx wrangler secret put SECRET_NAMEで環境変数を設定。値は設定したら見れない開発環境ではダッシュボード/ターミナルで設定した環境変数にアクセスできない為、DocsのWorkerを試す場合は
.dev.varsというファイルを作成し同じ環境変数を書く。(Tanstack-start等は.env.localで良い)
型:
ターミナルで
npx wrangler typesと打つとworker-configuration.d.tsに型が生成される。
バインディング
バインディングの作成・削除の流れは共通している。
作成:
CLIコマンドで作成すると
wrangler.jsoncにバインディングが追加され、次にwrangler typesで型を生成。
削除:
CLIコマンドでd1やkvといったバインディングを削除し、
wrangler.jsoncから該当するものを削除、そしてwrangler typesで型からも削除する。
.gitignore
以下はOpenNextのテンプレート
# dependencies
/node_modules
# misc
.DS_Store
*.pem
# local env files
.env*.local
.env
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
# OpenNext
/.open-next
# wrangler files
.wrangler
.dev.vars*
!.dev.vars.example
!.env.examplegeolocation
Workersを使えば、ある程度正確な地理情報を取得できる。
export default {
async fetch(req): Promise<Response> {
const ALLOWED_ORIGINS = ["https://xxx.vercel.app" , "http://localhost:3000"];
const origin = req.headers.get("Origin") || "";
const allowOrigin = ALLOWED_ORIGINS.includes(origin) ? origin : "";
if (!ALLOWED_ORIGINS.includes(origin)) {
return Response.json({ error: "Forbidden origin" }, { status: 403 });
}
const country = req.cf?.country;
const city = req.cf?.city;
const continent = req.cf?.continent;
const latitude = req.cf?.latitude;
const longitude = req.cf?.longitude;
const postalCode = req.cf?.postalCode;
const region = req.cf?.region;
const timezone = req.cf?.timezone;
const data = {
country,
city,
continent,
latitude,
longitude,
postalCode,
region,
timezone,
};
if (!latitude || !longitude) {
return Response.json({ error: "No data available" }, { status: 500 });
}
return new Response(JSON.stringify(data), {
status: 200,
headers: {
"Access-Control-Allow-Origin": allowOrigin,
"Access-Control-Allow-Methods": "GET",
},
});
},
} satisfies ExportedHandler;KV
key/valueペアのストレージ。使い方はRedisと似ている。
一括取得や最新のxx件取得のような使い方をしたいならD1を作成した方が良い。
npx wrangler kv namespace create/delete NAMESPACERenv.NAMESPACE.get(key, value);
env.NAMESPACE.put(key, value);
env.NAMESPACE.delete(key, value);既存のキーにputをしたら値は上書きされる。
await c.env.SUMMARY.put(id, result.response, {
expirationTtl: 60 * 60 * 24 * 5, // 5日間
});データを保持する期限を設定
expiration
後ろにTtlを付けると今から(リクエスト時)カウント、無い場合は未来の特定時点を固定で指定。
Rate-Limit
https://developers.cloudflare.com/workers/runtime-apis/bindings/rate-limit/
wrangler.jsonc に以下を追加
"ratelimits": [
{
"name": "RATE_LIMITER",
"namespace_id": "1001",
"simple": {
"limit": 10,
"period": 60
}
}
]index.ts :
import { env } from "cloudflare:workers";
export default {
async fetch(req): Promise<Response> {
const { pathname } = new URL(req.url);
const { success } = await env.RATE_LIMITER.limit({
key: pathname,
});
if (!success) {
return new Response(`429 Failure – rate limit exceeded for ${pathname}`, {
status: 429,
});
}D1
npx wrangler d1 create/delete DB_NAME "d1_databases": [
{
...
"remote": true,
},
],D1はローカルとリモートで違うD1データベースを使う。
ORMを組み合わせる場合、リモートのD1を使う設定(
remote": true)にした方がやりやすい。使い方はPrisma側の全体記事を参照