• #cloudflare
  • #workers
  • #routes
  • #static-files
開発完了

Cloudflare Workers Routesと静的ファイルの罠

Cloudflare Workers Routesでワイルドカード(*)を使うと、本来Workerで処理する必要がない静的ファイルまでWorkerを経由してしまう。この問題の仕組みと解決策を解説する。

結論

Workers Routesに含まれるパスは、静的ファイルでも全てWorkerに転送される。

静的ファイルを直接Cloudflare Pagesから配信したい場合は、そのパスをRoutesから除外する必要がある。

問題の状況

やりたかったこと

OGP画像の配信方式を変更:

  • 変更前: Cloudflare Workerで動的に生成
  • 変更後: ビルド時に静的画像を生成し、Cloudflare Pagesから配信

静的画像は public/og/pages/design-principles/ に配置。URLは https://example.com/og/pages/design-principles/a/55.png のようになる。

起きた問題

静的画像をデプロイしたのに、OGP画像が404で表示されない。

原因

wrangler.tomlに以下のルート設定があった:

routes = [
  { pattern = "example.com/og/pages/*", zone_name = "example.com" }
]

この/og/pages/*というワイルドカードが問題。

リクエストの流れ

ブラウザ: /og/pages/design-principles/a/55.png をリクエスト
    ↓
Cloudflare: Workers Routesをチェック
    ↓
「/og/pages/*」にマッチする!
    ↓
Workerに転送(Pagesには行かない)
    ↓
Worker: design-principlesのハンドラーがない
    ↓
404 Not Found

重要な点: Workerのコードでハンドラーを削除しても、Routes設定が残っていればリクエストはWorkerに来る

解決策

ベストプラクティス:ルートを個別に指定する

# ❌ 悪い例:ワイルドカードで全部まとめる
routes = [
  { pattern = "example.com/og/pages/*", zone_name = "example.com" }
]

# ✅ 良い例:Workerで処理するパスだけ個別に指定
routes = [
  { pattern = "example.com/og/pages/coding-standards/*", zone_name = "example.com" },
  { pattern = "example.com/og/pages/jleague/*", zone_name = "example.com" },
  { pattern = "example.com/og/pages/general/*", zone_name = "example.com" }
]
# /og/pages/design-principles/* はルートに含めない → Pagesから直接配信

なぜ個別指定がベストプラクティスか

  1. パフォーマンス: 静的ファイルがWorkerを経由しない(レイテンシ削減)
  2. コスト: Workerの実行回数が減る(無料枠の節約)
  3. 明確性: 何がWorkerで処理されるか一目でわかる
  4. Cloudflareの推奨: 必要なパスだけWorkerにルーティングする

代替案:Workerでフォールバック

ルート設定を変更できない場合、Worker内でオリジンにフォールバックする方法もある:

// Workerのコード
if (url.pathname.startsWith('/og/pages/design-principles/')) {
  return fetch(request) // オリジン(Pages)に転送
}

ただし、これは無駄にWorkerを経由するので非推奨。

図解

ルートに含まれている場合

[ブラウザ]
    ↓ /og/pages/design-principles/a/55.png
[Cloudflare Edge]
    ↓ Routes: /og/pages/* にマッチ
[Worker] ← ここを経由してしまう
    ↓ ハンドラーなし
[404 Not Found]

ルートから除外した場合

[ブラウザ]
    ↓ /og/pages/design-principles/a/55.png
[Cloudflare Edge]
    ↓ Routes: マッチするルートなし
[Cloudflare Pages] ← 直接配信
    ↓
[静的ファイル: 55.png]

まとめ

項目ワイルドカード個別指定
設定の手間少ない多い
パフォーマンス無駄なWorker経由あり最適
コストWorker実行回数増最小限
明確性曖昧明確

Workers Routesは「Workerで処理が必要なパス」だけを指定する。 静的ファイルは含めない。

この原則を守れば、「静的ファイルをデプロイしたのに404」という問題は起きない。