【設定・環境構築】Next.js アプリを OpenNext で Cloudflare Workers にデプロイする

この記事でわかること
- OpenNext(@opennextjs/cloudflare)で Next.js を Workers 向けにビルドする手順
- wrangler.jsonc の書き方と nodejs_compat_v2 で何が使えて何が使えないか
- fs がない環境でファイルを読んでいた箇所の逃げ方
- Pages と Workers をどちらにするかの判断基準(別記事との関係)
Next.js 15 以上(App Router)、Cloudflare アカウントと Workers の有効化、wrangler CLI が入っていること。
はじめに
Next.js は Vercel 向けに最適化されているため、Cloudflare Workers で直接動かすことはできません。しかし OpenNext というブリッジライブラリを使うと、Next.js のビルド出力を Workers 互換に変換してくれます。
この記事では anoni アプリ(Next.js 16 / App Router)を Cloudflare Workers に移行した際の手順とハマりポイントを紹介します。
別記事との関係について: 別記事の Cloudflare Workers→Pages出戻り記 では、このブログ自体を Workers から Pages に戻した話を書いています。矛盾しているように見えますが、対象が違います。あちらは「ほぼ静的なコンテンツサイト」で CDN 直返しの速さが勝ち、こちらは「Node.js API やセッションを使うアプリケーション」で Workers が向いています。
なお 2026 年時点では Cloudflare Pages がメンテナンスモードに入り、@cloudflare/next-on-pages も非推奨になりました。これから新規で選ぶなら、本記事の Workers + OpenNext が公式の推奨経路です。
1. OpenNext の導入
OpenNext は Next.js を Cloudflare Workers 向けにビルドするブリッジです。
bun add @opennextjs/cloudflare wrangler設定ファイルを作成します。
// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({});2. wrangler.jsonc の設定
{
"name": "anoni-dev",
"main": ".open-next/worker.js",
"compatibility_date": "2025-02-26",
"compatibility_flags": ["nodejs_compat_v2"],
"assets": {
"directory": ".open-next/assets",
"binding": "ASSETS"
}
}nodejs_compat_v2 フラグにより、Workers 上で一部の Node.js API がポリフィルされます。ただし fs、net、child_process などファイルや TCP を直接触る系は使えません。Workers にはそもそもファイルシステムがないので、ポリフィルの問題ではなく原理的な制約です。3. fs モジュール問題の解決
キャラクタープロンプト(.md ファイル)を fs.readFileSync で読んでいた箇所がエラーになります。解決策は TypeScript の定数ファイルに変換して埋め込むことです。
const PROMPTS: Record<string, string> = {
"char-a.md": `ここにプロンプト内容...`,
"char-b.md": `ここにプロンプト内容...`,
};
export function getPrompt(fileName: string): string {
const content = PROMPTS[fileName];
if (!content) throw new Error(`Prompt not found: ${fileName}`);
return content;
}.md → .ts の変換は一見不思議に見えるので、PR では「Workers には fs がない」背景を必ず記載しましょう。内容が大きい場合は、ビルド時に生成するか R2 などに置いて fetch する選択肢もあります。4. Suspense 境界の追加
useSearchParams() を使うコンポーネントには Suspense 境界が必須です。これは Workers 固有の話ではなく、Next.js 15 以降の仕様です(ビルドが止まります)。
import { Suspense } from "react";
export default function ChatPage() {
return (
<>
<Suspense>
<WelcomeToast />
</Suspense>
<ChatPageContainer />
</>
);
}5. ビルドとデプロイ
# Workers 向けビルド
npx opennextjs-cloudflare build
# デプロイ
npx wrangler deployTips
wrangler secret put コマンドか、Cloudflare ダッシュボードの Workers 設定から追加できます。まとめ
- OpenNext (
@opennextjs/cloudflare) を使えば Next.js App Router アプリを Workers にデプロイ可能 fsが使えない制約は、ファイル内容を TS 定数に変換して解決useSearchParams()には Suspense 境界を忘れずにnodejs_compat_v2フラグで Node.js API の一部がポリフィルされる
更新履歴
- 別記事の「Workers→Pages 出戻り記」と矛盾して見えないよう、対象が違うこと(静的サイト vs アプリケーション)と、2026年時点では Workers + OpenNext が公式の推奨経路であることを冒頭に注記。コード例に入っていたプロダクト固有の名前を汎用な形に差し替え。Suspense 境界が Workers 固有ではなく Next.js 15 以降の仕様であることを明記。fs が使えない理由と他の選択肢を補足。コードブロックにファイルパスのキャプションを追加し、callout の色指定を他記事と揃えた。「この記事でわかること」「対象読者」「前提条件」を概要プロパティへ移動。


