Back to all posts
Tutorial

終極指南:使用 OpenNext 將 Next.js 15 從 Cloudflare Pages 遷移到 Workers

如果你一直在構建 Next.js 15 應用程式,並嘗試使用 @cloudflare/next-on-pages 將它們部署到 Cloudflare Pages,那麼你很可能已經碰壁了。

令人頭疼的 "Invalid prerender config" 錯誤、靜態與動態路由渲染的不一致,以及 Edge 執行階段配置的衝突,一直是社群的重大痛點。在我的個人網站上為了除錯這些確切的問題耗費了數小時之後,我終於找到了一個無懈可擊的解決方案:使用 OpenNext 從 Cloudflare Pages 遷移到 Cloudflare Workers。

在本指南中,我將向你展示為什麼 Next.js 在 Pages 上會失敗,以及如何將你的架構乾淨俐落地遷移到 Cloudflare Workers,實現完美且健壯的部署。


痛點:Next-on-Pages 的侷限性

Cloudflare Pages 最初是為純靜態網站設計的。雖然它已經演變為支援伺服器端渲染 (SSR) 和 Edge Functions(透過 @cloudflare/next-on-pages),但它與 Next.js 15 的 App Router 的整合仍然很脆弱。

當你在專案中混合使用靜態 SSG 路由(如部落格文章)和動態 edge 路由(如 API 端點或資料庫查詢)時,構建過程通常會崩潰:

Error: Invalid prerender config for /app/[locale]/about
The following routes were not configured to run with the Edge Runtime...

根本原因在於 Vercel 的構建輸出所期望的函式結構與 next-on-pages 在 Pages 環境下解析它們的方式之間存在不匹配。


解決方案:OpenNext 和 Cloudflare Workers

現代的方法是停止與 Pages 的構建系統作鬥爭,轉而使用 OpenNext (@opennextjs/cloudflare) 並直接部署到 Cloudflare Workers。

Workers 提供了一個真正的 Serverless 執行環境,它與 Next.js 的 SSR 和 API 路由要求完美契合,而靜態檔案則由 Cloudflare Assets 處理。

這是逐步的遷移路徑。


第一步:安裝依賴

移除 next-on-pages 並安裝針對 Cloudflare 的 OpenNext:

npm uninstall @cloudflare/next-on-pages
npm install -D @opennextjs/cloudflare

第二步:配置 OpenNext

在專案根目錄下建立一個 open-next.config.ts 檔案。這會告訴 OpenNext 如何為了 Cloudflare 調整你的 Next.js 構建:

import type { OpenNextConfig } from 'open-next/types/open-next.js';

export default {
  default: {
    override: {
      wrapper: 'cloudflare-node',
      converter: 'edge',
      incrementalCache: 'dummy',
      tagCache: 'dummy',
      queue: 'dummy',
    },
  },
  middleware: {
    external: true,
    override: {
      wrapper: 'cloudflare-edge',
      converter: 'edge',
      proxyExternalRequest: 'fetch',
    },
  },
} as OpenNextConfig;

第三步:為 Workers 設定 Wrangler

你需要一個 wrangler.jsonc(或 wrangler.toml)來定義你的 Worker 部署。請注意我們將主入口指向了生成的 OpenNext worker,並綁定了靜態資產。

{
  "main": ".open-next/worker.js",
  "name": "your-project-name",
  "compatibility_date": "2026-06-15",
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "assets": {
    "directory": ".open-next/assets",
    "binding": "ASSETS"
  }
}

第四步:更新構建指令碼

更新你的 package.json,首先使用 Next.js 構建,然後使用 OpenNext 處理:

"scripts": {
  "build": "next build && opennextjs-cloudflare",
  "preview": "npm run build && wrangler dev",
  "deploy": "npm run build && wrangler deploy"
}

第五步:清理 Edge 配置

有了 OpenNext 之後,你不再需要為了迎合構建系統而在每個動態檔案的頂部嚴格強制使用 export const runtime = 'edge'。OpenNext 的 cloudflare-node 包裝器智慧地處理了 Node.js API 和 Edge API,極大地簡化了你的程式碼庫。


那 Cloudflare R2 呢?

在遷移過程中,你可能會想是否需要配置一個 Cloudflare R2 儲存桶。

簡單的回答是:不,目前不需要。 你的 Next.js 靜態資產(圖片、CSS、JS 檔案)由在 wrangler.jsonc 中定義的 Cloudflare Assets 綁定完美地提供服務。

然而,如果你的應用程式擴展到需要處理使用者上傳的媒體、大型影片或海量資料集,R2 可以無縫整合到這種 Worker 架構中。你只需在 wrangler.jsonc 中綁定 R2 儲存桶,並透過伺服器操作(Server Actions)或 API 路由中的 env.MY_BUCKET 存取它。

最終成果

透過使用 OpenNext 遷移到 Cloudflare Workers,你實現了:

  • 零構建錯誤:不再為預渲染配置而抓狂。
  • 完美的在地化:國際化路由 (/[locale]/) 開箱即用。
  • Node.js 相容性:nodejs_compat 標誌允許支援更廣泛的 npm 套件。

Cloudflare Pages 對於簡單的靜態網站來說非常棒,但對於雄心勃勃的 Next.js 15 應用程式,基於 Cloudflare Workers 的 OpenNext 才是明確的前進方向。