cloudflare-nextjs
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare Next.js Deployment Skill
Cloudflare Next.js 部署技能指南
Deploy Next.js applications to Cloudflare Workers using the OpenNext Cloudflare adapter for production-ready serverless Next.js hosting.
使用OpenNext Cloudflare适配器将Next.js应用部署到Cloudflare Workers,实现生产就绪的无服务器Next.js托管。
Use This Skill When
适用场景
- Deploying Next.js applications (App Router or Pages Router) to Cloudflare Workers
- Need server-side rendering (SSR), static site generation (SSG), or incremental static regeneration (ISR) on Cloudflare
- Migrating existing Next.js apps from Vercel, AWS, or other platforms to Cloudflare
- Building full-stack Next.js applications with Cloudflare services (D1, R2, KV, Workers AI)
- Need React Server Components, Server Actions, or Next.js middleware on Workers
- Want global edge deployment with Cloudflare's network
- 将Next.js应用(App Router或Pages Router)部署到Cloudflare Workers
- 需要在Cloudflare上实现服务端渲染(SSR)、静态站点生成(SSG)或增量静态再生(ISR)
- 将现有Next.js应用从Vercel、AWS或其他平台迁移到Cloudflare
- 构建集成Cloudflare服务(D1、R2、KV、Workers AI)的全栈Next.js应用
- 需要在Workers上使用React Server Components、Server Actions或Next.js中间件
- 希望借助Cloudflare网络实现全球边缘部署
Key Concepts
核心概念
OpenNext Adapter Architecture
OpenNext适配器架构
The OpenNext Cloudflare adapter () transforms Next.js build output into Cloudflare Worker-compatible format. This is fundamentally different from standard Next.js deployments:
@opennextjs/cloudflare- Node.js Runtime Required: Uses Node.js runtime in Workers (NOT Edge runtime)
- Dual Development Workflow: Test in both Next.js dev server AND workerd runtime
- Custom Build Pipeline: → OpenNext transformation → Worker deployment
next build - Cloudflare-Specific Configuration: Requires wrangler.jsonc and open-next.config.ts
OpenNext Cloudflare适配器()可将Next.js构建输出转换为Cloudflare Worker兼容格式。这与标准Next.js部署存在本质区别:
@opennextjs/cloudflare- 需要Node.js运行时:在Workers中使用Node.js运行时(而非Edge运行时)
- 双开发工作流:同时在Next.js开发服务器和workerd运行时中测试
- 自定义构建流水线:→ OpenNext转换 → Worker部署
next build - Cloudflare专属配置:需要wrangler.jsonc和open-next.config.ts文件
Critical Differences from Standard Next.js
与标准Next.js的关键差异
| Aspect | Standard Next.js | Cloudflare Workers |
|---|---|---|
| Runtime | Node.js or Edge | Node.js (via nodejs_compat) |
| Dev Server | | |
| Deployment | Platform-specific | |
| Worker Size | No limit | 3 MiB (free) / 10 MiB (paid) |
| Database Connections | Global clients OK | Must be request-scoped |
| Image Optimization | Built-in | Via Cloudflare Images |
| Caching | Next.js cache | OpenNext config + Workers cache |
| 维度 | 标准Next.js | Cloudflare Workers |
|---|---|---|
| 运行时 | Node.js或Edge | Node.js(通过nodejs_compat) |
| 开发服务器 | | |
| 部署方式 | 平台专属 | |
| Worker大小 | 无限制 | 3 MiB(免费版)/ 10 MiB(付费版) |
| 数据库连接 | 全局客户端可用 | 必须为请求作用域 |
| 图片优化 | 内置支持 | 通过Cloudflare Images实现 |
| 缓存机制 | Next.js缓存 | OpenNext配置 + Workers缓存 |
Setup Patterns
配置模式
New Project Setup
新项目配置
Use Cloudflare's (C3) CLI to scaffold a new Next.js project pre-configured for Workers:
create-cloudflarebash
npm create cloudflare@latest -- my-next-app --framework=nextWhat this does:
- Runs Next.js official setup tool ()
create-next-app - Installs adapter
@opennextjs/cloudflare - Creates with correct configuration
wrangler.jsonc - Creates for caching configuration
open-next.config.ts - Adds deployment scripts to
package.json - Optionally deploys immediately to Cloudflare
Development workflow:
bash
npm run dev # Next.js dev server (fast reloads)
npm run preview # Test in workerd runtime (production-like)
npm run deploy # Build and deploy to Cloudflare使用Cloudflare的(C3)CLI工具快速搭建预配置Workers的Next.js项目:
create-cloudflarebash
npm create cloudflare@latest -- my-next-app --framework=next该命令完成的操作:
- 运行Next.js官方初始化工具()
create-next-app - 安装适配器
@opennextjs/cloudflare - 创建配置正确的文件
wrangler.jsonc - 创建用于缓存配置的文件
open-next.config.ts - 在中添加部署脚本
package.json - 可选:立即部署到Cloudflare
开发工作流:
bash
npm run dev # Next.js开发服务器(快速热重载)
npm run preview # 在workerd运行时中测试(生产环境模拟)
npm run deploy # 构建并部署到CloudflareExisting Project Migration
现有项目迁移
To add the OpenNext adapter to an existing Next.js application:
为现有Next.js应用添加OpenNext适配器的步骤:
1. Install the adapter
1. 安装适配器
bash
npm install --save-dev @opennextjs/cloudflarebash
npm install --save-dev @opennextjs/cloudflare2. Create wrangler.jsonc
2. 创建wrangler.jsonc
jsonc
{
"name": "my-next-app",
"compatibility_date": "2025-05-05",
"compatibility_flags": ["nodejs_compat"]
}Critical configuration:
- : Minimum
compatibility_date(for FinalizationRegistry support)2025-05-05 - : Must include
compatibility_flags(for Node.js runtime)nodejs_compat
jsonc
{
"name": "my-next-app",
"compatibility_date": "2025-05-05",
"compatibility_flags": ["nodejs_compat"]
}关键配置:
- :最低要求
compatibility_date(支持FinalizationRegistry)2025-05-05 - :必须包含
compatibility_flags(用于Node.js运行时)nodejs_compat
3. Create open-next.config.ts
3. 创建open-next.config.ts
typescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// Caching configuration (optional)
// See: https://opennext.js.org/cloudflare/caching
});typescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// 缓存配置(可选)
// 参考:https://opennext.js.org/cloudflare/caching
});4. Update package.json scripts
4. 更新package.json脚本
json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
}
}Script purposes:
- : Next.js development server (fast iteration)
dev - : Build + run in workerd runtime (test before deploy)
preview - : Build + deploy to Cloudflare
deploy - : Generate TypeScript types for Cloudflare bindings
cf-typegen
json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
}
}脚本用途:
- :Next.js开发服务器(快速迭代)
dev - :构建并在workerd运行时中运行(部署前测试)
preview - :构建并部署到Cloudflare
deploy - :为Cloudflare绑定生成TypeScript类型
cf-typegen
5. Ensure Node.js runtime (not Edge)
5. 确保使用Node.js运行时(而非Edge)
Remove Edge runtime exports from your app:
typescript
// ❌ REMOVE THIS (Edge runtime not supported)
export const runtime = "edge";
// ✅ Use Node.js runtime (default)
// No export needed - Node.js is default移除应用中的Edge运行时导出:
typescript
// ❌ 移除该代码(不支持Edge运行时)
export const runtime = "edge";
// ✅ 使用Node.js运行时(默认)
// 无需额外导出 - Node.js为默认选项Development Workflow
开发工作流
Dual Testing Strategy
双测试策略
Always test in BOTH environments:
-
Next.js Dev Server ()
npm run dev- Fast hot reloading
- Best developer experience
- Runs in Node.js (not production runtime)
- Use for rapid iteration
-
Workerd Runtime ()
npm run preview- Runs in production-like environment
- Catches runtime-specific issues
- Slower rebuild times
- Required before deployment
务必在两种环境中都进行测试:
-
Next.js开发服务器()
npm run dev- 快速热重载
- 最佳开发体验
- 在Node.js中运行(非生产运行时)
- 用于快速迭代开发
-
Workerd运行时()
npm run preview- 在类生产环境中运行
- 捕获运行时专属问题
- 重建速度较慢
- 部署前必须执行
When to Use Each
适用场景区分
bash
undefinedbash
undefinedIterating on UI/logic → Use Next.js dev server
迭代UI/逻辑 → 使用Next.js开发服务器
npm run dev
npm run dev
Testing integrations (D1, R2, KV) → Use preview
测试集成(D1、R2、KV)→ 使用preview
npm run preview
npm run preview
Before deploying → ALWAYS test preview
部署前 → 务必测试preview
npm run preview
npm run preview
Deploy to production
部署到生产环境
npm run deploy
undefinednpm run deploy
undefinedConfiguration Requirements
配置要求
Wrangler Configuration
Wrangler配置
Minimum requirements in :
wrangler.jsoncjsonc
{
"name": "your-app-name",
"compatibility_date": "2025-05-05", // Minimum for FinalizationRegistry
"compatibility_flags": ["nodejs_compat"] // Required for Node.js runtime
}wrangler.jsoncjsonc
{
"name": "your-app-name",
"compatibility_date": "2025-05-05", // 支持FinalizationRegistry的最低版本
"compatibility_flags": ["nodejs_compat"] // Node.js运行时必需
}Environment Variables for Package Exports
包导出的环境变量
If using npm packages with multiple export conditions, create :
.envenv
WRANGLER_BUILD_CONDITIONS=""
WRANGLER_BUILD_PLATFORM="node"This ensures Wrangler prioritizes the export when available.
node如果使用包含多个导出条件的npm包,创建文件:
.envenv
WRANGLER_BUILD_CONDITIONS=""
WRANGLER_BUILD_PLATFORM="node"这将确保Wrangler在可用时优先选择导出。
nodeCloudflare Bindings Integration
Cloudflare绑定集成
Add bindings in :
wrangler.jsoncjsonc
{
"name": "your-app-name",
"compatibility_date": "2025-05-05",
"compatibility_flags": ["nodejs_compat"],
// D1 Database
"d1_databases": [
{
"binding": "DB",
"database_name": "production-db",
"database_id": "your-database-id"
}
],
// R2 Storage
"r2_buckets": [
{
"binding": "BUCKET",
"bucket_name": "your-bucket"
}
],
// KV Storage
"kv_namespaces": [
{
"binding": "KV",
"id": "your-kv-id"
}
],
// Workers AI
"ai": {
"binding": "AI"
}
}Access bindings in Next.js via :
process.envtypescript
// app/api/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
// Access Cloudflare bindings
const env = process.env as any;
// D1 Database query
const result = await env.DB.prepare('SELECT * FROM users').all();
// R2 Storage access
const file = await env.BUCKET.get('file.txt');
// KV Storage access
const value = await env.KV.get('key');
// Workers AI inference
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
prompt: 'Hello AI'
});
return Response.json({ result });
}在中添加绑定:
wrangler.jsoncjsonc
{
"name": "your-app-name",
"compatibility_date": "2025-05-05",
"compatibility_flags": ["nodejs_compat"],
// D1数据库
"d1_databases": [
{
"binding": "DB",
"database_name": "production-db",
"database_id": "your-database-id"
}
],
// R2存储
"r2_buckets": [
{
"binding": "BUCKET",
"bucket_name": "your-bucket"
}
],
// KV存储
"kv_namespaces": [
{
"binding": "KV",
"id": "your-kv-id"
}
],
// Workers AI
"ai": {
"binding": "AI"
}
}通过在Next.js中访问绑定:
process.envtypescript
// app/api/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
// 访问Cloudflare绑定
const env = process.env as any;
// D1数据库查询
const result = await env.DB.prepare('SELECT * FROM users').all();
// R2存储访问
const file = await env.BUCKET.get('file.txt');
// KV存储访问
const value = await env.KV.get('key');
// Workers AI推理
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
prompt: 'Hello AI'
});
return Response.json({ result });
}Error Prevention (10+ Documented Errors)
错误预防(10余种已记录错误)
1. Worker Size Limit Exceeded (3 MiB - Free Plan)
1. Worker大小限制超出(免费版3 MiB)
Error:
"Your Worker exceeded the size limit of 3 MiB"Cause: Workers Free plan limits Worker size to 3 MiB (gzip-compressed)
Solutions:
- Upgrade to Workers Paid plan (10 MiB limit)
- Analyze bundle size and remove unused dependencies
- Use dynamic imports to code-split large dependencies
Bundle analysis:
bash
npx opennextjs-cloudflare build
cd .open-next/server-functions/default错误信息:
"Your Worker exceeded the size limit of 3 MiB"原因:Workers免费版限制Worker大小为3 MiB(gzip压缩后)
解决方案:
- 升级到Workers付费版(限制为10 MiB)
- 分析包大小并移除未使用的依赖
- 使用动态导入对大型依赖进行代码分割
包分析命令:
bash
npx opennextjs-cloudflare build
cd .open-next/server-functions/defaultAnalyze handler.mjs.meta.json with ESBuild Bundle Analyzer
使用ESBuild Bundle Analyzer分析handler.mjs.meta.json
**Source**: https://opennext.js.org/cloudflare/troubleshooting#worker-size-limits
---
**来源**:https://opennext.js.org/cloudflare/troubleshooting#worker-size-limits
---2. Worker Size Limit Exceeded (10 MiB - Paid Plan)
2. Worker大小限制超出(付费版10 MiB)
Error:
"Your Worker exceeded the size limit of 10 MiB"Cause: Unnecessary code bundled into Worker
Debug workflow:
- Run
npx opennextjs-cloudflare build - Navigate to
.open-next/server-functions/default - Analyze using ESBuild Bundle Analyzer
handler.mjs.meta.json - Identify and remove/externalize large dependencies
错误信息:
"Your Worker exceeded the size limit of 10 MiB"原因:不必要的代码被打包到Worker中
调试流程:
- 运行
npx opennextjs-cloudflare build - 进入目录
.open-next/server-functions/default - 使用ESBuild Bundle Analyzer分析
handler.mjs.meta.json - 识别并移除/外部化大型依赖
3. FinalizationRegistry Not Defined
3. FinalizationRegistry未定义
Error:
"ReferenceError: FinalizationRegistry is not defined"Cause: in wrangler.jsonc is too old
compatibility_dateSolution: Update to or later:
compatibility_date2025-05-05jsonc
{
"compatibility_date": "2025-05-05" // Minimum for FinalizationRegistry
}错误信息:
"ReferenceError: FinalizationRegistry is not defined"原因:wrangler.jsonc中的版本过旧
compatibility_date解决方案:将更新为或更高版本:
compatibility_date2025-05-05jsonc
{
"compatibility_date": "2025-05-05" // 支持FinalizationRegistry的最低版本
}4. Cannot Perform I/O on Behalf of Different Request
4. 无法代表其他请求执行I/O操作
Error:
"Cannot perform I/O on behalf of a different request"Cause: Database client created globally and reused across requests
Problem code:
typescript
// ❌ WRONG: Global DB client
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export async function GET() {
// This will fail - pool created in different request context
const result = await pool.query('SELECT * FROM users');
return Response.json(result);
}Solution: Create database clients inside request handlers:
typescript
// ✅ CORRECT: Request-scoped DB client
import { Pool } from 'pg';
export async function GET() {
// Create client within request context
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const result = await pool.query('SELECT * FROM users');
await pool.end();
return Response.json(result);
}Alternative: Use Cloudflare D1 (designed for Workers) instead of external databases:
typescript
// ✅ BEST: Use D1 (no connection pooling needed)
export async function GET(request: NextRequest) {
const env = process.env as any;
const result = await env.DB.prepare('SELECT * FROM users').all();
return Response.json(result);
}错误信息:
"Cannot perform I/O on behalf of a different request"原因:数据库客户端在全局创建并跨请求复用
错误代码示例:
typescript
// ❌ 错误:全局DB客户端
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export async function GET() {
// 此操作会失败 - 连接池在不同请求上下文中创建
const result = await pool.query('SELECT * FROM users');
return Response.json(result);
}解决方案:在请求处理程序内部创建数据库客户端:
typescript
// ✅ 正确:请求作用域的DB客户端
import { Pool } from 'pg';
export async function GET() {
// 在请求上下文中创建客户端
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const result = await pool.query('SELECT * FROM users');
await pool.end();
return Response.json(result);
}替代方案(推荐):使用Cloudflare D1(为Workers设计)替代外部数据库:
typescript
// ✅ 最佳方案:使用D1(无需连接池)
export async function GET(request: NextRequest) {
const env = process.env as any;
const result = await env.DB.prepare('SELECT * FROM users').all();
return Response.json(result);
}5. NPM Package Import Failures
5. NPM包导入失败
Error:
"Could not resolve '<package>'"Cause: Missing flag or package export conditions
nodejs_compatSolution 1: Enable flag:
nodejs_compatjsonc
{
"compatibility_flags": ["nodejs_compat"]
}Solution 2: For packages with multiple exports, create :
.envenv
WRANGLER_BUILD_CONDITIONS=""
WRANGLER_BUILD_PLATFORM="node"错误信息:
"Could not resolve '<package>'"原因:缺少标志或包导出条件配置错误
nodejs_compat解决方案1:启用标志:
nodejs_compatjsonc
{
"compatibility_flags": ["nodejs_compat"]
}解决方案2:对于包含多个导出的包,创建文件:
.envenv
WRANGLER_BUILD_CONDITIONS=""
WRANGLER_BUILD_PLATFORM="node"6. Failed to Load Chunk (Turbopack)
6. 加载代码块失败(Turbopack)
Error:
"Failed to load chunk server/chunks/ssr/"Cause: Next.js built with Turbopack ()
next build --turboSolution: Use standard build (Turbopack not supported by adapter):
json
{
"scripts": {
"build": "next build" // ✅ Correct
// "build": "next build --turbo" // ❌ Don't use Turbopack
}
}错误信息:
"Failed to load chunk server/chunks/ssr/"原因:使用Turbopack构建Next.js()
next build --turbo解决方案:使用标准构建方式(适配器不支持Turbopack):
json
{
"scripts": {
"build": "next build" // ✅ 正确
// "build": "next build --turbo" // ❌ 不要使用Turbopack
}
}7. SSRF Vulnerability (CVE-2025-6087)
7. SSRF漏洞(CVE-2025-6087)
Vulnerability: Server-Side Request Forgery via endpoint
/_next/imageAffected versions: < 1.3.0
@opennextjs/cloudflareSolution: Upgrade to version 1.3.0 or later:
bash
npm install --save-dev @opennextjs/cloudflare@^1.3.0Impact: Allows unauthenticated users to proxy arbitrary remote content
漏洞描述:通过端点实现服务器端请求伪造
/_next/image受影响版本: < 1.3.0
@opennextjs/cloudflare解决方案:升级到1.3.0或更高版本:
bash
npm install --save-dev @opennextjs/cloudflare@^1.3.0影响:允许未授权用户代理任意远程内容
8. Durable Objects Binding Warnings
8. Durable Objects绑定警告
Warning:
"You have defined bindings to the following internal Durable Objects... will not work in local development, but they should work in production"Cause: OpenNext uses Durable Objects for caching (, )
DOQueueHandlerDOShardedTagCacheSolution: Safe to ignore - warning is expected behavior
Alternative (to suppress warning): Define Durable Objects in separate Worker with own config
警告信息:
"You have defined bindings to the following internal Durable Objects... will not work in local development, but they should work in production"原因:OpenNext使用Durable Objects实现缓存(、)
DOQueueHandlerDOShardedTagCache解决方案:可安全忽略 - 该警告为预期行为
替代方案(抑制警告):在单独的Worker中定义Durable Objects并使用独立配置
9. Prisma + D1 Middleware Conflicts
9. Prisma + D1中间件冲突
Error: Build errors when using + in Next.js middleware
@prisma/client@prisma/adapter-d1Cause: Database initialization in middleware context
Workaround: Initialize Prisma client in route handlers, not middleware
错误信息:在Next.js中间件中使用 + 时出现构建错误
@prisma/client@prisma/adapter-d1原因:在中间件上下文中初始化数据库
临时解决方案:在路由处理程序中初始化Prisma客户端,而非中间件
10. cross-fetch Library Errors
10. cross-fetch库错误
Error: Errors when using libraries that depend on
cross-fetchCause: OpenNext patches deployment package causing to try using Node.js libraries when native fetch is available
cross-fetchSolution: Use native API directly instead of :
fetchcross-fetchtypescript
// ✅ Use native fetch
const response = await fetch('https://api.example.com/data');
// ❌ Avoid cross-fetch
// import fetch from 'cross-fetch';错误信息:使用依赖的库时出现错误
cross-fetch原因:OpenNext会修补部署包,导致在原生fetch可用时尝试使用Node.js库
cross-fetch解决方案:直接使用原生API替代:
fetchcross-fetchtypescript
// ✅ 使用原生fetch
const response = await fetch('https://api.example.com/data');
// ❌ 避免使用cross-fetch
// import fetch from 'cross-fetch';11. Windows Development Issues
11. Windows开发问题
Issue: Full Windows support not guaranteed
Cause: Underlying Next.js tooling issues on Windows
Solutions:
- Use WSL (Windows Subsystem for Linux)
- Use virtual machine with Linux
- Use Linux-based CI/CD for deployments
问题描述:无法保证完整的Windows支持
原因:Next.js底层工具在Windows上存在问题
解决方案:
- 使用WSL(Windows Subsystem for Linux)
- 使用Linux虚拟机
- 使用基于Linux的CI/CD进行部署
Feature Support Matrix
功能支持矩阵
| Feature | Status | Notes |
|---|---|---|
| App Router | ✅ Fully Supported | Latest App Router features work |
| Pages Router | ✅ Fully Supported | Legacy Pages Router supported |
| Route Handlers | ✅ Fully Supported | API routes work as expected |
| React Server Components | ✅ Fully Supported | RSC fully functional |
| Server Actions | ✅ Fully Supported | Server Actions work |
| SSG | ✅ Fully Supported | Static Site Generation |
| SSR | ✅ Fully Supported | Server-Side Rendering |
| ISR | ✅ Fully Supported | Incremental Static Regeneration |
| Middleware | ✅ Supported | Except Node.js middleware (15.2+) |
| Image Optimization | ✅ Supported | Via Cloudflare Images |
| Partial Prerendering (PPR) | ✅ Supported | Experimental in Next.js |
| Composable Caching | ✅ Supported | |
| Response Streaming | ✅ Supported | Streaming responses work |
| ✅ Supported | Post-response async work |
| Node.js Middleware (15.2+) | ❌ Not Supported | Future support planned |
| Edge Runtime | ❌ Not Supported | Use Node.js runtime |
| 功能 | 状态 | 说明 |
|---|---|---|
| App Router | ✅ 完全支持 | 最新App Router功能均可使用 |
| Pages Router | ✅ 完全支持 | 支持传统Pages Router |
| Route Handlers | ✅ 完全支持 | API路由正常工作 |
| React Server Components | ✅ 完全支持 | RSC功能完整 |
| Server Actions | ✅ 完全支持 | Server Actions可正常使用 |
| SSG | ✅ 完全支持 | 静态站点生成 |
| SSR | ✅ 完全支持 | 服务端渲染 |
| ISR | ✅ 完全支持 | 增量静态再生 |
| Middleware | ✅ 支持 | 不支持Node.js中间件(15.2+) |
| 图片优化 | ✅ 支持 | 通过Cloudflare Images实现 |
| 部分预渲染(PPR) | ✅ 支持 | Next.js中的实验性功能 |
| 可组合缓存 | ✅ 支持 | |
| 响应流 | ✅ 支持 | 流式响应可正常工作 |
| ✅ 支持 | 响应后异步操作 |
| Node.js中间件(15.2+) | ❌ 不支持 | 计划在未来版本中支持 |
| Edge运行时 | ❌ 不支持 | 使用Node.js运行时 |
Integration with Cloudflare Services
与Cloudflare服务的集成
D1 Database (SQL)
D1数据库(SQL)
typescript
// app/api/users/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as any;
const result = await env.DB.prepare(
'SELECT * FROM users WHERE active = ?'
).bind(true).all();
return Response.json(result.results);
}
export async function POST(request: NextRequest) {
const env = process.env as any;
const { name, email } = await request.json();
const result = await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind(name, email).run();
return Response.json({ id: result.meta.last_row_id });
}Wrangler config:
jsonc
{
"d1_databases": [
{
"binding": "DB",
"database_name": "production-db",
"database_id": "your-database-id"
}
]
}See also: skill for complete D1 patterns
cloudflare-d1typescript
// app/api/users/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as any;
const result = await env.DB.prepare(
'SELECT * FROM users WHERE active = ?'
).bind(true).all();
return Response.json(result.results);
}
export async function POST(request: NextRequest) {
const env = process.env as any;
const { name, email } = await request.json();
const result = await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind(name, email).run();
return Response.json({ id: result.meta.last_row_id });
}Wrangler配置:
jsonc
{
"d1_databases": [
{
"binding": "DB",
"database_name": "production-db",
"database_id": "your-database-id"
}
]
}另请参考:技能文档获取完整D1使用模式
cloudflare-d1R2 Storage (Object Storage)
R2存储(对象存储)
typescript
// app/api/upload/route.ts
import type { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const env = process.env as any;
const formData = await request.formData();
const file = formData.get('file') as File;
// Upload to R2
await env.BUCKET.put(file.name, file.stream(), {
httpMetadata: {
contentType: file.type
}
});
return Response.json({ success: true, filename: file.name });
}
export async function GET(request: NextRequest) {
const env = process.env as any;
const { searchParams } = new URL(request.url);
const filename = searchParams.get('file');
const object = await env.BUCKET.get(filename);
if (!object) {
return new Response('Not found', { status: 404 });
}
return new Response(object.body, {
headers: {
'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream'
}
});
}See also: skill for complete R2 patterns
cloudflare-r2typescript
// app/api/upload/route.ts
import type { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const env = process.env as any;
const formData = await request.formData();
const file = formData.get('file') as File;
// 上传到R2
await env.BUCKET.put(file.name, file.stream(), {
httpMetadata: {
contentType: file.type
}
});
return Response.json({ success: true, filename: file.name });
}
export async function GET(request: NextRequest) {
const env = process.env as any;
const { searchParams } = new URL(request.url);
const filename = searchParams.get('file');
const object = await env.BUCKET.get(filename);
if (!object) {
return new Response('Not found', { status: 404 });
}
return new Response(object.body, {
headers: {
'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream'
}
});
}另请参考:技能文档获取完整R2使用模式
cloudflare-r2Workers AI (Model Inference)
Workers AI(模型推理)
typescript
// app/api/ai/route.ts
import type { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const env = process.env as any;
const { prompt } = await request.json();
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
prompt
});
return Response.json(response);
}Wrangler config:
jsonc
{
"ai": {
"binding": "AI"
}
}See also: skill for complete AI patterns
cloudflare-workers-aitypescript
// app/api/ai/route.ts
import type { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const env = process.env as any;
const { prompt } = await request.json();
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
prompt
});
return Response.json(response);
}Wrangler配置:
jsonc
{
"ai": {
"binding": "AI"
}
}另请参考:技能文档获取完整AI使用模式
cloudflare-workers-aiKV Storage (Key-Value)
KV存储(键值对)
typescript
// app/api/cache/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as any;
const { searchParams } = new URL(request.url);
const key = searchParams.get('key');
const value = await env.KV.get(key);
return Response.json({ key, value });
}
export async function PUT(request: NextRequest) {
const env = process.env as any;
const { key, value, ttl } = await request.json();
await env.KV.put(key, value, { expirationTtl: ttl });
return Response.json({ success: true });
}See also: skill for complete KV patterns
cloudflare-kvtypescript
// app/api/cache/route.ts
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as any;
const { searchParams } = new URL(request.url);
const key = searchParams.get('key');
const value = await env.KV.get(key);
return Response.json({ key, value });
}
export async function PUT(request: NextRequest) {
const env = process.env as any;
const { key, value, ttl } = await request.json();
await env.KV.put(key, value, { expirationTtl: ttl });
return Response.json({ success: true });
}另请参考:技能文档获取完整KV使用模式
cloudflare-kvImage Optimization
图片优化
Next.js image optimization works via Cloudflare Images. Configure in :
open-next.config.tstypescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
imageOptimization: {
loader: 'cloudflare'
}
});Usage in components:
tsx
import Image from 'next/image';
export default function Avatar() {
return (
<Image
src="/avatar.jpg"
alt="User avatar"
width={200}
height={200}
// Automatically optimized via Cloudflare Images
/>
);
}Billing: Cloudflare Images usage is billed separately
Next.js图片优化通过Cloudflare Images实现。在中配置:
open-next.config.tstypescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
imageOptimization: {
loader: 'cloudflare'
}
});在组件中使用:
tsx
import Image from 'next/image';
export default function Avatar() {
return (
<Image
src="/avatar.jpg"
alt="用户头像"
width={200}
height={200}
// 自动通过Cloudflare Images优化
/>
);
}计费说明:Cloudflare Images使用量单独计费
Caching Configuration
缓存配置
Configure caching behavior in :
open-next.config.tstypescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// Custom cache configuration
cache: {
// Override default cache behavior
// See: https://opennext.js.org/cloudflare/caching
}
});Default behavior: OpenNext provides sensible caching defaults
Advanced usage: See official OpenNext caching documentation
在中配置缓存行为:
open-next.config.tstypescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig({
// 自定义缓存配置
cache: {
// 覆盖默认缓存行为
// 参考:https://opennext.js.org/cloudflare/caching
}
});默认行为:OpenNext提供合理的缓存默认值
高级用法:参考OpenNext官方缓存文档
Known Limitations
已知限制
Not Yet Supported
暂不支持的功能
-
Node.js Middleware (Next.js 15.2+)
- Introduced in Next.js 15.2
- Support planned for future releases
- Use standard middleware for now
-
Edge Runtime
- Only Node.js runtime supported
- Remove from your app
export const runtime = "edge"
-
Full Windows Support
- Development on Windows not fully guaranteed
- Use WSL, VM, or Linux-based CI/CD
-
Node.js中间件(Next.js 15.2+)
- 在Next.js 15.2中引入
- 计划在未来版本中支持
- 目前使用标准中间件
-
Edge运行时
- 仅支持Node.js运行时
- 从应用中移除
export const runtime = "edge"
-
完整Windows支持
- Windows开发环境未完全兼容
- 使用WSL、虚拟机或基于Linux的CI/CD
Worker Size Constraints
Worker大小限制
- Free plan: 3 MiB limit (gzip-compressed)
- Paid plan: 10 MiB limit (gzip-compressed)
- Monitor bundle size during development
- Use dynamic imports for code splitting
- 免费版:3 MiB限制(gzip压缩后)
- 付费版:10 MiB限制(gzip压缩后)
- 开发过程中监控包大小
- 使用动态导入进行代码分割
Database Connections
数据库连接
- External database clients (PostgreSQL, MySQL) must be request-scoped
- Cannot reuse connections across requests (Workers limitation)
- Prefer Cloudflare D1 for database needs (designed for Workers)
- 外部数据库客户端(PostgreSQL、MySQL)必须为请求作用域
- 无法跨请求复用连接(Workers限制)
- 优先使用Cloudflare D1(为Workers设计)
Deployment
部署
Deploy from Local Machine
从本地机器部署
bash
undefinedbash
undefinedBuild and deploy in one command
一键构建并部署
npm run deploy
npm run deploy
Or step by step:
或分步执行:
npx opennextjs-cloudflare build
npx opennextjs-cloudflare deploy
undefinednpx opennextjs-cloudflare build
npx opennextjs-cloudflare deploy
undefinedDeploy from CI/CD
从CI/CD部署
Configure deployment command in your CI/CD system:
bash
npm run deployExamples:
- GitHub Actions:
.github/workflows/deploy.yml - GitLab CI:
.gitlab-ci.yml - Cloudflare Workers Builds: Auto-detects
npm run deploy
Environment variables: Set secrets in Cloudflare dashboard or CI/CD system
在CI/CD系统中配置部署命令:
bash
npm run deploy示例:
- GitHub Actions:
.github/workflows/deploy.yml - GitLab CI:
.gitlab-ci.yml - Cloudflare Workers Builds:自动检测
npm run deploy
环境变量:在Cloudflare控制台或CI/CD系统中设置密钥
Custom Domains
自定义域名
Add custom domain in Cloudflare dashboard:
- Navigate to Workers & Pages
- Select your Worker
- Settings → Domains & Routes
- Add custom domain
DNS: Domain must be on Cloudflare (zone required)
在Cloudflare控制台中添加自定义域名:
- 导航到Workers & Pages
- 选择您的Worker
- 设置 → 域名与路由
- 添加自定义域名
DNS要求:域名必须托管在Cloudflare(需要Zone)
TypeScript Support
TypeScript支持
Generate types for Cloudflare bindings:
bash
npm run cf-typegenCreates with types for your bindings:
cloudflare-env.d.tstypescript
// cloudflare-env.d.ts (auto-generated)
interface CloudflareEnv {
DB: D1Database;
BUCKET: R2Bucket;
KV: KVNamespace;
AI: Ai;
}Use in route handlers:
typescript
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as CloudflareEnv;
// Now env.DB, env.BUCKET, etc. are typed
}为Cloudflare绑定生成类型:
bash
npm run cf-typegen生成包含绑定类型的文件:
cloudflare-env.d.tstypescript
// cloudflare-env.d.ts(自动生成)
interface CloudflareEnv {
DB: D1Database;
BUCKET: R2Bucket;
KV: KVNamespace;
AI: Ai;
}在路由处理程序中使用:
typescript
import type { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const env = process.env as CloudflareEnv;
// 现在env.DB、env.BUCKET等均已类型化
}Testing
测试
Local Testing (Development)
本地测试(开发阶段)
bash
undefinedbash
undefinedNext.js dev server (fast iteration)
Next.js开发服务器(快速迭代)
npm run dev
undefinednpm run dev
undefinedLocal Testing (Production-like)
本地测试(类生产环境)
bash
undefinedbash
undefinedWorkerd runtime (catches Workers-specific issues)
Workerd运行时(捕获Workers专属问题)
npm run preview
undefinednpm run preview
undefinedIntegration Testing
集成测试
Always test in mode before deploying:
previewbash
undefined部署前务必在模式下测试:
previewbash
undefinedBuild and run in workerd
构建并在workerd中运行
npm run preview
npm run preview
Test bindings (D1, R2, KV, AI)
测试绑定(D1、R2、KV、AI)
Test middleware
测试中间件
Test API routes
测试API路由
Test SSR/ISR behavior
测试SSR/ISR行为
undefinedundefinedMigration from Other Platforms
从其他平台迁移
From Vercel
从Vercel迁移
- Copy existing Next.js project
- Run existing project migration steps (above)
- Update environment variables in Cloudflare dashboard
- Replace Vercel-specific features:
- Vercel Postgres → Cloudflare D1
- Vercel Blob → Cloudflare R2
- Vercel KV → Cloudflare KV
- Vercel Edge Config → Cloudflare KV
- Test thoroughly with
npm run preview - Deploy with
npm run deploy
- 复制现有Next.js项目
- 执行上述现有项目迁移步骤
- 在Cloudflare控制台中更新环境变量
- 替换Vercel专属功能:
- Vercel Postgres → Cloudflare D1
- Vercel Blob → Cloudflare R2
- Vercel KV → Cloudflare KV
- Vercel Edge Config → Cloudflare KV
- 使用进行全面测试
npm run preview - 使用部署
npm run deploy
From AWS / Other Platforms
从AWS / 其他平台迁移
Same process as Vercel migration - the adapter handles Next.js standard features automatically.
与Vercel迁移流程相同 - 适配器会自动处理Next.js标准功能。
Resources
资源
Official Documentation
官方文档
- OpenNext Cloudflare: https://opennext.js.org/cloudflare
- Cloudflare Next.js Guide: https://developers.cloudflare.com/workers/framework-guides/web-apps/nextjs/
- Next.js Docs: https://nextjs.org/docs
- OpenNext Cloudflare:https://opennext.js.org/cloudflare
- Cloudflare Next.js指南:https://developers.cloudflare.com/workers/framework-guides/web-apps/nextjs/
- Next.js文档:https://nextjs.org/docs
Troubleshooting
故障排除
- Troubleshooting Guide: https://opennext.js.org/cloudflare/troubleshooting
- Known Issues: https://opennext.js.org/cloudflare/known-issues
- GitHub Issues: https://github.com/opennextjs/opennextjs-cloudflare/issues
Related Skills
相关技能
- - Base Worker setup with Hono + Vite + React
cloudflare-worker-base - - D1 database integration
cloudflare-d1 - - R2 object storage
cloudflare-r2 - - KV key-value storage
cloudflare-kv - - Workers AI integration
cloudflare-workers-ai - - Vector database for RAG
cloudflare-vectorize
- - 基于Hono + Vite + React的基础Worker配置
cloudflare-worker-base - - D1数据库集成
cloudflare-d1 - - R2对象存储
cloudflare-r2 - - KV键值对存储
cloudflare-kv - - Workers AI集成
cloudflare-workers-ai - - 用于RAG的向量数据库
cloudflare-vectorize
Quick Reference
快速参考
Essential Commands
核心命令
bash
undefinedbash
undefinedNew project
新项目初始化
npm create cloudflare@latest -- my-next-app --framework=next
npm create cloudflare@latest -- my-next-app --framework=next
Development
开发
npm run dev # Fast iteration (Next.js dev server)
npm run preview # Test in workerd (production-like)
npm run dev # 快速迭代(Next.js开发服务器)
npm run preview # 类生产环境测试(workerd运行时)
Deployment
部署
npm run deploy # Build and deploy to Cloudflare
npm run deploy # 构建并部署到Cloudflare
TypeScript
TypeScript类型生成
npm run cf-typegen # Generate binding types
undefinednpm run cf-typegen # 生成绑定类型
undefinedCritical Configuration
关键配置
jsonc
// wrangler.jsonc
{
"compatibility_date": "2025-05-05", // Minimum!
"compatibility_flags": ["nodejs_compat"] // Required!
}jsonc
// wrangler.jsonc
{
"compatibility_date": "2025-05-05", // 最低要求!
"compatibility_flags": ["nodejs_compat"] // 必需!
}Common Pitfalls
常见陷阱
- ❌ Using Edge runtime → ✅ Use Node.js runtime
- ❌ Global DB clients → ✅ Request-scoped clients
- ❌ Old compatibility_date → ✅ Use 2025-05-05+
- ❌ Missing nodejs_compat → ✅ Add to compatibility_flags
- ❌ Only testing in → ✅ Always test
devbefore deploypreview - ❌ Using Turbopack → ✅ Use standard Next.js build
Production Tested: Official Cloudflare support and active community
Token Savings: ~59% vs manual setup
Errors Prevented: 10+ documented issues
Last Verified: 2025-10-21
- ❌ 使用Edge运行时 → ✅ 使用Node.js运行时
- ❌ 全局DB客户端 → ✅ 请求作用域客户端
- ❌ 旧版compatibility_date → ✅ 使用2025-05-05及以上版本
- ❌ 缺少nodejs_compat → ✅ 添加到compatibility_flags
- ❌ 仅在中测试 → ✅ 部署前务必测试
devpreview - ❌ 使用Turbopack → ✅ 使用标准Next.js构建
生产验证:官方Cloudflare支持,活跃社区维护
时间节省:相比手动配置节省约59%的时间
错误预防:10余种已记录问题
最后验证时间:2025-10-21