框架整合:把 Next.js、React、Astro 部署到 Workers | Cloudflare 完整教學
這一篇要教你把主流前端框架部署到 Cloudflare Workers。上一篇我們把 Workers Static Assets 的
assets設定一行一行拆開來實作;這一篇就把這些設定套用到真實框架上——從create-cloudflare(C3)起手,逐一看 Next.js(@opennextjs/cloudflare)、React/Vite、Astro、Remix、Hono 各自的整合方式與適配器(adapter),說清楚 SSR 與靜態的差別,以及用錯 adapter、Node API 相容、edge runtime 這些常見坑。本篇也為整個 Pages 段落作收尾。
前言
上一篇《Workers Static Assets 靜態託管》,我們把 wrangler.jsonc 裡的 assets 設定攤開來,一行一行講清楚:directory 指向建置輸出、not_found_handling 決定找不到檔案怎麼辦、run_worker_first 控制哪些路由先進 Worker、main 補上後端邏輯。那一篇教的是「手工設定」;但實際開發時,你不會手刻這些檔案——你會用一個框架(React、Next.js、Astro……),讓它的官方適配器幫你自動產生這些設定。
先給一句話定義:
框架整合(Framework Integration)指的是:透過各框架的官方 Cloudflare 適配器(adapter)或建置設定,把框架的建置產物(靜態檔案 + 伺服器端程式碼)自動對應到 Workers 的
assets.directory與main入口,讓你用熟悉的框架語法開發,卻部署在 Cloudflare 的全球邊緣網路上。
打個比方會更好懂。上一篇的 assets 設定,就像一台通用的引擎與底盤;而框架適配器,就是為不同車型(Next.js、Astro、Remix)量身打造的變速箱——它把框架這具「引擎」的輸出,精準地接到 Workers 這副「底盤」上。React/Vite 這種純靜態產物,引擎輸出的是「已經做好的成品」(靜態 HTML/JS),幾乎不用變速箱,直接放上底盤就能跑;而 Next.js、Astro SSR 這種要「每次請求即時產生 HTML」的,就得靠對應的適配器把伺服器端邏輯翻譯成 Workers 看得懂的 main 入口。選對變速箱(adapter),車才跑得順;選錯(例如用了給 Pages 的舊 adapter),就會格格不入。
讀完這篇你會掌握:
- C3 起手式——用
npm create cloudflare@latest一鍵建立各框架的 Workers 專案骨架。 - 靜態 vs SSR 的判斷——哪些框架/模式是純靜態(不用 adapter)、哪些是 SSR(需要 adapter 產生
main)。 - 五大框架的整合方式——Next.js(
@opennextjs/cloudflare)、React/Vite、Astro、Remix、Hono 各自怎麼接。 - 常見坑——用錯 adapter、Node API 相容(
nodejs_compat)、SSR 與 edge runtime 的取捨。
核心概念
一、一切的分水嶺:純靜態 vs 需要伺服器
在談任何框架之前,先建立最重要的一條判斷線:這個框架的產物,是「純靜態」還是「需要伺服器端執行」? 這條線決定了你需不需要 adapter、wrangler.jsonc 要不要寫 main。
- 純靜態(SSG / SPA):建置時就把所有 HTML(或一個 SPA 的
index.html)產好,執行期不需要跑任何框架程式碼。只需要assets.directory,不需要 adapter、不需要main。 例如 React/Vite 的 SPA、Astro 的output: 'static'、Hugo/Jekyll。 - SSR(伺服器端渲染):每次請求都要在伺服器端執行框架程式碼、即時產生 HTML。需要一個 Cloudflare adapter 把框架的 server 產物翻譯成 Workers 的
main入口。 例如 Next.js 的 SSR、Astro 的output: 'server'、Remix。
一句話總結這張對照:adapter 的本質,就是「幫框架產生 Workers 的 main 入口」的工具。純靜態框架不需要 main,自然也不需要 adapter;有 SSR 才需要。
這條分水嶺為什麼這麼重要?因為它直接決定了你的部署成本與複雜度。純靜態站的每個請求都由邊緣直接提供、不計入 Worker 調用次數(這正是上一篇強調的「靜態請求免費」),而且沒有伺服器端程式碼,幾乎不可能出現執行期錯誤。SSR 則相反:每次請求都要跑框架程式碼,會計入調用、也可能因為 Node API 相容或資料庫查詢而出錯。因此在動手整合任何框架前,先問自己一個問題:這個網站的內容,是「建置時就固定好」,還是「每次請求都可能不同」? 部落格、文件、行銷頁多半屬於前者(純靜態);而需要登入、個人化、即時資料的應用則屬於後者(SSR)。判斷清楚了,後面選 adapter、寫設定才不會走冤枉路。
二、各框架整合方式對照表
下表把主流框架在 Workers 上的整合方式整理成一覽(套件名稱與版本細節請以各框架官方文件為準):
| 框架 | 整合方式 | 是否需要 adapter | 對應 wrangler.jsonc |
|---|---|---|---|
| React + Vite(SPA) | 純 assets + 選用 @cloudflare/vite-plugin | 否(純靜態) | 只設 assets.directory + not_found_handling |
| Next.js | @opennextjs/cloudflare 適配器 | 是 | main 指向 .open-next/worker.js |
| Astro(SSR) | @astrojs/cloudflare 適配器 | 是 | main 指向 dist/server/entry.mjs |
| Astro(靜態) | 無 adapter,output: 'static' | 否 | 只設 assets.directory |
| Remix | Workers 適配器(C3 產生) | 是 | main 指向 server 產物 |
| Hono | 原生執行,無需 adapter | 否(直接跑) | main 指向你的 Hono app |
| SvelteKit | @sveltejs/adapter-cloudflare | 是 | adapter 自動產生 |
| Nuxt | Nitro preset: 'cloudflare-module' | 是(Nitro 內建) | preset 自動產生 |
幾個關鍵術語先講清楚:
- adapter(適配器):框架與部署平台之間的翻譯層,負責把框架的 build 產物轉成目標平台(這裡是 Workers)的格式。
@opennextjs/cloudflare:部署 Next.js 到 Workers 的官方適配器。注意它與舊版@cloudflare/next-on-pages(部署到 Pages)不同,新專案用前者。bindings:Workers 的資源綁定(D1、KV、R2、AI……)。各框架都提供了在 server 端(如 Server Components、loader、API route)存取env的方式,語法各有不同。
三、bindings 在各框架裡怎麼拿
框架整合不只是「跑起來」,還要能在框架的伺服器端程式碼裡存取 Cloudflare 的 bindings。各框架的取用入口不同,先有個印象:
- Next.js:
import { getCloudflareContext } from '@opennextjs/cloudflare',再const { env } = await getCloudflareContext()。 - Astro:
Astro.locals.runtime.env。 - Remix:loader 的
context.cloudflare.env。 - SvelteKit:
platform.env(在+page.server.ts等 server load 裡)。 - Hono:handler 的
c.env。
實作範例
理論看完,我們用「由簡到繁」的順序,把各框架的最小整合實際寫出來。
1. C3 起手式:一鍵建立框架專案
不論你要用哪個框架,最省事的起點都是 create-cloudflare(C3)——它會幫你選框架、裝依賴、產生 wrangler.jsonc 與正確的 adapter 設定:
# 互動式:會問你要哪個框架、要不要部署
npm create cloudflare@latest my-app
# 直接指定框架(範例:Next.js、React、Astro、Remix)
npm create cloudflare@latest my-next-app -- --framework=next
npm create cloudflare@latest my-react-app -- --framework=react
npm create cloudflare@latest my-astro-app -- --framework=astro
npm create cloudflare@latest my-remix-app -- --framework=remix
C3 產生的專案已經幫你把 assets、main、adapter、compatibility_flags 都設好了。如果你是全新專案,強烈建議直接用 C3,而不是自己從零手刻設定。(可用的 --framework 選項與其預設會隨版本調整,請以 C3 當下的互動選單或官方文件為準。)
為什麼建議用 C3 而不是手工設定?因為每個框架的建置產物路徑、需要的 compatibility_flags、adapter 版本搭配都有各自的細節,手動抄設定很容易漏掉一兩處(最常見的就是漏開 nodejs_compat,或把 main 指錯目錄)。C3 會依你選的框架自動裝上正確的 adapter、產生對應的 wrangler.jsonc 與 package.json 指令,還會問你要不要順便部署。換句話說,C3 把上一篇我們手工拆解的那些 assets 與 main 設定「自動化」了——你只需要專注在寫應用程式,不用記每個框架的設定慣例。等專案跑起來後,你仍然可以打開 wrangler.jsonc 微調(例如加上 D1、KV、R2 綁定),但起點交給 C3 最省事、也最不容易出錯。
2. React + Vite:純靜態,不需要 adapter
React/Vite 的預設產物是 SPA(單頁應用),是最單純的情況——不需要任何 adapter,只要把建置輸出設成 assets.directory、開啟 SPA fallback 即可:
// wrangler.jsonc — React/Vite SPA,零 Worker 程式碼
{
"name": "my-react-app",
"compatibility_date": "2026-01-01",
"assets": {
"directory": "./dist",
"not_found_handling": "single-page-application" // 前端路由的必要設定
}
}
npm run build # Vite 建置,輸出到 ./dist
npx wrangler deploy
如果想要更順的本地開發體驗(在 vite dev 裡就能存取 bindings),可以加上官方的 @cloudflare/vite-plugin:
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { cloudflare } from '@cloudflare/vite-plugin';
export default defineConfig({
plugins: [
react(),
cloudflare() // 讓 vite dev 模擬 Workers 執行環境與 bindings
]
});
這個 plugin 屬於「錦上添花」——沒有它,純靜態 React 一樣能部署;有了它,開發時能就近測試 env.DB、env.KV 等綁定。
3. Next.js:@opennextjs/cloudflare 適配器
Next.js 是最需要 adapter 的框架,因為它有 SSR、Server Components、Route Handlers、ISR 等大量伺服器端功能。官方適配器是 @opennextjs/cloudflare(部署到 Workers);舊版 @cloudflare/next-on-pages(部署到 Pages)已不建議用於新專案。
新專案最快的路是用 C3;現有專案則用適配器提供的遷移指令:
# 新專案(C3 會裝好 @opennextjs/cloudflare)
npm create cloudflare@latest my-next-app -- --framework=next
# 現有 Next.js 專案遷移(指令與旗標請以官方文件為準)
npx @opennextjs/cloudflare migrate
wrangler.jsonc 的重點是 main 指向 open-next 的產物、assets 指向它產出的靜態目錄,並開啟 nodejs_compat:
// wrangler.jsonc — Next.js on Workers(欄位以官方文件為準)
{
"name": "my-next-app",
"main": ".open-next/worker.js", // adapter 產生的 Worker 入口
"compatibility_date": "2026-08-01",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": ".open-next/assets", // adapter 產生的靜態資源
"binding": "ASSETS"
},
// ISR 快取(選用):需要一個 R2 bucket
"r2_buckets": [
{ "binding": "NEXT_INC_CACHE_R2_BUCKET", "bucket_name": "next-cache" }
]
}
在 Server Components 或 Route Handler 裡存取 bindings,透過 getCloudflareContext():
// app/api/users/route.ts — 在 Next.js 伺服器端存取 D1
import { getCloudflareContext } from '@opennextjs/cloudflare';
export async function GET() {
const { env } = await getCloudflareContext();
const { results } = await env.DB.prepare('SELECT * FROM users').all();
return Response.json(results);
}
@opennextjs/cloudflare 已支援 App Router 與 Pages Router、React Server Components、Route Handlers、Server Actions,以及 SSG / SSR / ISR。要特別記住:它不支援把路由標成 export const runtime = 'edge'(Edge Runtime)——這點下一節會展開。
4. Astro:內建 Cloudflare 適配器
Astro 很有彈性:純內容站可用 output: 'static'(純靜態,不用 adapter);要 SSR 或混合模式,就加上 @astrojs/cloudflare:
npm create cloudflare@latest my-astro-app -- --framework=astro
# 或在現有 Astro 專案中加上適配器
npx astro add cloudflare
// astro.config.mjs — Astro SSR on Workers
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server', // 'static' 純靜態 / 'server' SSR
adapter: cloudflare({
platformProxy: { enabled: true } // 本地開發模擬 Workers 環境
})
});
在 Astro 頁面/元件裡,透過 Astro.locals.runtime.env 存取 bindings:
---
// src/pages/index.astro — 伺服器端查詢 D1
const { DB } = Astro.locals.runtime.env;
const { results: products } = await DB.prepare(
'SELECT * FROM products ORDER BY created_at DESC LIMIT 10'
).all();
---
<ul>
{products.map((p) => <li>{p.name} — ${p.price}</li>)}
</ul>
SSR 模式下,wrangler.jsonc 的 main 指向 Astro 產出的 server 入口、assets 指向 client 目錄:
// wrangler.jsonc — Astro SSR
{
"name": "my-astro-app",
"main": "dist/server/entry.mjs",
"compatibility_date": "2026-01-01",
"compatibility_flags": ["nodejs_compat"],
"assets": { "directory": "dist/client" },
"d1_databases": [{ "binding": "DB", "database_id": "your-db-id" }]
}
若你的 Astro 站是純內容(部落格、文件),用 output: 'static' 建置後,連 main 都不用寫,回到上一篇的「純靜態站」型態即可。
5. Hono:原生跑在 Workers,無需 adapter
Hono 是為 Web 標準與邊緣環境設計的輕量框架,可以直接原生跑在 Workers 上,不需要任何 adapter——你的 Worker 入口本身就是一個 Hono app:
// src/index.ts — Hono 直接當作 Worker 入口
import { Hono } from 'hono';
interface Env {
DB: D1Database;
ASSETS: Fetcher;
}
const app = new Hono<{ Bindings: Env }>();
// API 路由,c.env 直接拿到 bindings
app.get('/api/users', async (c) => {
const { results } = await c.env.DB.prepare('SELECT * FROM users').all();
return c.json(results);
});
export default app; // 不需要 adapter,直接 export
// wrangler.jsonc — Hono + 前端靜態資源
{
"name": "my-hono-app",
"main": "src/index.ts",
"compatibility_date": "2026-01-01",
"assets": {
"directory": "./dist",
"run_worker_first": ["/api/*"] // 只有 API 先進 Hono,其餘走免費靜態
}
}
這裡把上一篇的 run_worker_first: ["/api/*"] 派上用場:Hono 只處理 /api/*,其餘前端靜態檔案由邊緣直送、不計費。這種「Hono 寫後端 API + 前端框架靜態產物」的組合,是 Workers 上很常見的輕量全端模式。
6. Remix:透過 C3 產生 Workers 適配器
Remix 同樣是 SSR 框架,舊的 @remix-run/cloudflare-pages(Pages 版)已棄用,改用 C3 產生的 Workers 版設定:
npm create cloudflare@latest my-remix-app -- --framework=remix
在 loader 裡透過 context.cloudflare.env 存取 bindings:
// app/routes/_index.tsx — Remix loader 存取 D1
import type { LoaderFunctionArgs } from '@remix-run/cloudflare';
import { json } from '@remix-run/cloudflare';
export async function loader({ context }: LoaderFunctionArgs) {
const { cloudflare } = context;
const { results } = await cloudflare.env.DB.prepare(
'SELECT * FROM products LIMIT 10'
).all();
return json({ products: results });
}
wrangler.jsonc 的 main 指向 Remix 的 server build、assets 指向 client build,型態與 Astro SSR 幾乎一致(C3 會幫你產生,不用手刻)。
常見錯誤與最佳實踐
框架整合的坑,大多集中在「用錯適配器」「Node API 相容」「SSR 與 edge runtime 搞混」這三類。以下是最高頻的幾個。
坑一:Next.js 用了給 Pages 的舊 adapter(@cloudflare/next-on-pages)。
這是最常見的誤會。@cloudflare/next-on-pages 是部署到 Pages 的舊適配器,而現在官方主推的是部署到 Workers 的 @opennextjs/cloudflare。用錯了不只是設定不同,還會少掉 Workers 才有的能力(Durable Objects、Cron、更完整的 observability)。正確做法:新專案一律用 @opennextjs/cloudflare;既有的 next-on-pages 專案考慮遷移。(套件名稱與遷移路徑以官方文件為準。)
坑二:忘了開 nodejs_compat,SSR 框架跑不起來。
Next.js、Astro SSR、Remix 這類框架的伺服器端程式碼,常會用到 Node.js 的 API(如 Buffer、process、部分內建模組)。Workers 預設不提供完整 Node 環境,若沒設定就會在執行期報錯。正確做法:SSR 框架的 wrangler.jsonc 記得在 compatibility_flags 加上 "nodejs_compat"(C3 產生的專案通常已幫你加好;手動遷移時最容易漏)。
坑三:在 @opennextjs/cloudflare 上硬用 export const runtime = 'edge'。
有些 Next.js 教學會叫你把 API route 或頁面標成 Edge Runtime(export const runtime = 'edge'),但 @opennextjs/cloudflare 不支援這個標記。原因是:在 Workers 上你「本來就跑在邊緣」,不需要 Next.js 那套 Edge Runtime 抽象。正確做法:移除 runtime = 'edge' 標記,使用預設(Node.js 相容)執行環境即可——功能不會少,反而更完整。
坑四:把純靜態專案硬套 adapter,徒增複雜度。
反過來的錯誤:一個明明是 React SPA 或 Astro 純內容站的專案,卻去裝 SSR adapter、寫一堆 main。正確做法:先判斷「這個專案需不需要伺服器端渲染」。純靜態(SSG/SPA)就只設 assets.directory + not_found_handling,不碰 adapter;確定有 SSR 需求(即時資料、個人化頁面)才引入對應框架的 Cloudflare adapter。
坑五:分不清該讓框架處理路由,還是用 run_worker_first。
框架自己有一套路由(Next.js 的 App Router、Remix 的 file routes),而 Workers 也有 run_worker_first。兩者混用時容易打架。正確做法:用「官方 adapter 產生的 main」的框架(Next.js/Astro/Remix),路由交給框架、wrangler.jsonc 照 adapter 產生的設定走,不要自己亂加 run_worker_first;只有在「自己手寫 Worker(如 Hono)+ 前端靜態產物」的組合裡,才用 run_worker_first: ["/api/*"] 劃清 API 與靜態的界線。
最佳實踐小結:
- 新專案用 C3 起手——
npm create cloudflare@latest幫你把 adapter、main、assets、compatibility_flags一次設好。 - 先判斷靜態 vs SSR——純靜態只設
assets;SSR 才用對應框架的 Cloudflare adapter。 - Next.js 認
@opennextjs/cloudflare——不用舊的 next-on-pages,不用runtime = 'edge'。 - SSR 框架記得
nodejs_compat——避免 Node API 相容性報錯。 - Hono 直接跑——輕量 API/全端首選,搭配
run_worker_first與前端靜態產物。
小結
上一篇《Workers Static Assets 靜態託管》,我們把 assets 的每個選項拆開來實作,學會了手工設定靜態託管。這一篇《框架整合》,我們把這些設定套用到真實框架上:
- 分水嶺——純靜態(SSG/SPA)只需
assets、不用 adapter;SSR 需要 adapter 產生main入口。 - 五大框架——React/Vite(純靜態,選用
@cloudflare/vite-plugin)、Next.js(@opennextjs/cloudflare)、Astro(@astrojs/cloudflare)、Remix(C3 產生)、Hono(原生跑,無需 adapter)。 - C3 起手——
npm create cloudflare@latest一鍵建立各框架骨架,自動設好 adapter 與設定。 - 常見坑——用錯 Pages 舊 adapter、漏開
nodejs_compat、誤用runtime = 'edge'、純靜態硬套 adapter。
到這裡,我們從《Pages 與 Static Assets 總覽》的選型,到《Workers Static Assets 靜態託管》的手工實作,再到這一篇的框架整合,完整走完了 Cloudflare 前端與全端託管的 Pages 段落。你現在應該能自信地判斷:任何一個前端專案,該用純靜態還是 SSR、該不該用 adapter、wrangler.jsonc 該怎麼寫。
掌握了「怎麼把應用部署上去」,下一步就是「怎麼把應用設計得好」。下一篇《架構模式與反模式》,我們會拉高視角,談 Workers 應用常見的架構模式(以及那些看似方便、實則會踩雷的反模式)——如何組織 Worker、bindings、資料流,讓你的應用不只跑得起來,還跑得穩、擴得動。我們下一篇見。
想查閱各框架整合的官方最新指南與適配器套件細節,可以參考 Cloudflare Workers 框架指南官方文件(各框架適配器名稱、版本與支援矩陣以當下官方文件為準)。