cloudflare-opennext

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cloudflare OpenNext

Cloudflare OpenNext

Deploy Next.js applications to Cloudflare Workers using the
@opennextjs/cloudflare
adapter with full support for App Router, Pages Router, ISR, SSG, and Cloudflare bindings.
使用
@opennextjs/cloudflare
适配器将Next.js应用部署到Cloudflare Workers,全面支持App Router、Pages Router、ISR、SSG以及Cloudflare绑定。

When to Use

适用场景

  • Creating new Next.js apps for Cloudflare Workers
  • Migrating existing Next.js apps to Cloudflare
  • Configuring ISR/SSG caching with R2, KV, or D1
  • Accessing Cloudflare bindings (KV, R2, D1, Durable Objects, AI)
  • Using databases and ORMs (Drizzle, Prisma) in Next.js
  • Troubleshooting deployment issues or bundle size problems
  • 创建面向Cloudflare Workers的全新Next.js应用
  • 将现有Next.js应用迁移到Cloudflare
  • 配置基于R2、KV或D1的ISR/SSG缓存
  • 访问Cloudflare绑定(KV、R2、D1、Durable Objects、AI)
  • 在Next.js中使用数据库与ORM(Drizzle、Prisma)
  • 排查部署问题或包体积相关故障

Getting Started

快速开始

New App

全新应用

bash
npm create cloudflare@latest -- my-next-app --framework=next --platform=workers
cd my-next-app
npm run dev      # Local development with Next.js
npm run preview  # Preview in Workers runtime
npm run deploy   # Deploy to Cloudflare
bash
npm create cloudflare@latest -- my-next-app --framework=next --platform=workers
cd my-next-app
npm run dev      # 使用Next.js进行本地开发
npm run preview  # 在Workers运行时中预览
npm run deploy   # 部署到Cloudflare

Existing App Migration

现有应用迁移

bash
undefined
bash
undefined

1. Install dependencies

1. 安装依赖

npm install @opennextjs/cloudflare@latest npm install --save-dev wrangler@latest
npm install @opennextjs/cloudflare@latest npm install --save-dev wrangler@latest

2. Create wrangler.jsonc (see Configuration section)

2. 创建wrangler.jsonc(查看配置章节)

3. Create open-next.config.ts

3. 创建open-next.config.ts

4. Update next.config.ts

4. 更新next.config.ts

5. Add scripts to package.json

5. 向package.json添加脚本

6. Deploy

6. 部署

npm run deploy
undefined
npm run deploy
undefined

Core Concepts

核心概念

How OpenNext Works

OpenNext工作原理

The
@opennextjs/cloudflare
adapter:
  1. Runs
    next build
    to generate the Next.js build output
  2. Transforms the build output to work in Cloudflare Workers runtime
  3. Outputs to
    .open-next/
    directory with
    worker.js
    entry point
  4. Uses Workers Static Assets for static files (
    _next/static
    ,
    public
    )
@opennextjs/cloudflare
适配器的工作流程:
  1. 运行
    next build
    生成Next.js构建产物
  2. 转换构建产物以适配Cloudflare Workers运行时
  3. 将输出文件写入
    .open-next/
    目录,入口文件为
    worker.js
  4. 使用Workers静态资源托管静态文件(
    _next/static
    public

Node.js Runtime (Not Edge)

Node.js运行时(非Edge)

Critical: OpenNext uses Next.js Node.js runtime, NOT the Edge runtime:
typescript
// ❌ Remove this - Edge runtime not supported
export const runtime = "edge";

// ✅ Default Node.js runtime - fully supported
// No export needed, this is the default
The Node.js runtime provides:
  • Full Node.js API compatibility via
    nodejs_compat
    flag
  • More Next.js features than Edge runtime
  • Access to all Cloudflare bindings
重点:OpenNext使用Next.js的Node.js运行时,而非Edge运行时:
typescript
// ❌ 请移除该行 - 不支持Edge运行时
export const runtime = "edge";

// ✅ 默认Node.js运行时 - 完全支持
// 无需额外导出,这是默认配置
Node.js运行时提供以下特性:
  • 通过
    nodejs_compat
    标志实现完整的Node.js API兼容性
  • 比Edge运行时支持更多Next.js特性
  • 可访问所有Cloudflare绑定

Configuration Files

配置文件

wrangler.jsonc

wrangler.jsonc

Minimal configuration for OpenNext:
jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-nextjs-app",
  "main": ".open-next/worker.js",
  "compatibility_date": "2024-12-30",
  "compatibility_flags": [
    "nodejs_compat",                    // Required for Node.js APIs
    "global_fetch_strictly_public"      // Security: prevent local IP fetches
  ],
  "assets": {
    "directory": ".open-next/assets",   // Static files
    "binding": "ASSETS"
  },
  "services": [
    {
      "binding": "WORKER_SELF_REFERENCE",
      "service": "my-nextjs-app"        // Must match "name" above
    }
  ],
  "images": {
    "binding": "IMAGES"                 // Optional: Enable image optimization
  }
}
Required settings:
  • nodejs_compat
    compatibility flag
  • compatibility_date
    >=
    2024-09-23
  • WORKER_SELF_REFERENCE
    service binding (must match worker name)
  • main
    and
    assets
    paths should not be changed
See references/configuration.md for complete configuration with R2, KV, D1 bindings.
OpenNext的最小化配置:
jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-nextjs-app",
  "main": ".open-next/worker.js",
  "compatibility_date": "2024-12-30",
  "compatibility_flags": [
    "nodejs_compat",                    // Node.js API支持所需
    "global_fetch_strictly_public"      // 安全设置:禁止本地IP请求
  ],
  "assets": {
    "directory": ".open-next/assets",   // 静态文件目录
    "binding": "ASSETS"
  },
  "services": [
    {
      "binding": "WORKER_SELF_REFERENCE",
      "service": "my-nextjs-app"        // 必须与上方的"name"一致
    }
  ],
  "images": {
    "binding": "IMAGES"                 // 可选:启用图片优化
  }
}
必填设置
  • nodejs_compat
    兼容性标志
  • compatibility_date
    需大于等于
    2024-09-23
  • WORKER_SELF_REFERENCE
    服务绑定必须与Worker名称一致
  • main
    assets
    路径请勿修改
查看references/configuration.md获取包含R2、KV、D1绑定的完整配置。

open-next.config.ts

open-next.config.ts

Configure caching and OpenNext behavior:
typescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";

export default defineCloudflareConfig({
  incrementalCache: r2IncrementalCache,
});
This file is auto-generated if not present. See references/caching.md for cache options.
配置缓存与OpenNext行为:
typescript
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";

export default defineCloudflareConfig({
  incrementalCache: r2IncrementalCache,
});
若该文件不存在,系统会自动生成。查看references/caching.md获取缓存选项详情。

next.config.ts

next.config.ts

Initialize OpenNext for local development:
typescript
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // Your Next.js configuration
};

export default nextConfig;

// Enable bindings access during `next dev`
import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
initOpenNextCloudflareForDev();
初始化OpenNext以支持本地开发:
typescript
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // 你的Next.js配置
};

export default nextConfig;

// 在`next dev`期间启用绑定访问
import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
initOpenNextCloudflareForDev();

.dev.vars

.dev.vars

Environment variables for local development:
bash
undefined
本地开发使用的环境变量:
bash
undefined

.dev.vars

.dev.vars

NEXTJS_ENV=development

The `NEXTJS_ENV` variable selects which Next.js `.env` file to load:
- `development` → `.env.development`
- `production` → `.env.production` (default)
NEXTJS_ENV=development

`NEXTJS_ENV`变量用于选择Next.js加载的`.env`文件:
- `development` → `.env.development`
- `production` → `.env.production`(默认值)

Accessing Cloudflare Bindings

访问Cloudflare绑定

Use
getCloudflareContext()
to access bindings in any route:
typescript
import { getCloudflareContext } from "@opennextjs/cloudflare";

// Route Handler (App Router)
export async function GET(request: Request) {
  const { env, cf, ctx } = getCloudflareContext();
  
  // Access KV
  const value = await env.MY_KV.get("key");
  
  // Access R2
  const object = await env.MY_BUCKET.get("file.txt");
  
  // Access D1
  const result = await env.DB.prepare("SELECT * FROM users").all();
  
  // Access Durable Objects
  const stub = env.MY_DO.idFromName("instance-1");
  const doResponse = await stub.fetch(request);
  
  // Access request info
  const country = cf?.country;
  
  // Background tasks
  ctx.waitUntil(logAnalytics());
  
  return Response.json({ value });
}

// API Route (Pages Router)
export default async function handler(req, res) {
  const { env } = getCloudflareContext();
  const data = await env.MY_KV.get("key");
  res.json({ data });
}

// Server Component
export default async function Page() {
  const { env } = getCloudflareContext();
  const data = await env.MY_KV.get("key");
  return <div>{data}</div>;
}
在任意路由中使用
getCloudflareContext()
访问绑定:
typescript
import { getCloudflareContext } from "@opennextjs/cloudflare";

// 路由处理器(App Router)
export async function GET(request: Request) {
  const { env, cf, ctx } = getCloudflareContext();
  
  // 访问KV
  const value = await env.MY_KV.get("key");
  
  // 访问R2
  const object = await env.MY_BUCKET.get("file.txt");
  
  // 访问D1
  const result = await env.DB.prepare("SELECT * FROM users").all();
  
  // 访问Durable Objects
  const stub = env.MY_DO.idFromName("instance-1");
  const doResponse = await stub.fetch(request);
  
  // 访问请求信息
  const country = cf?.country;
  
  // 后台任务
  ctx.waitUntil(logAnalytics());
  
  return Response.json({ value });
}

// API路由(Pages Router)
export default async function handler(req, res) {
  const { env } = getCloudflareContext();
  const data = await env.MY_KV.get("key");
  res.json({ data });
}

// 服务端组件
export default async function Page() {
  const { env } = getCloudflareContext();
  const data = await env.MY_KV.get("key");
  return <div>{data}</div>;
}

SSG Routes with Async Context

带异步上下文的SSG路由

For Static Site Generation routes, use async mode:
typescript
// In SSG route (generateStaticParams, etc.)
const { env } = await getCloudflareContext({ async: true });
const products = await env.DB.prepare("SELECT * FROM products").all();
Warning: During SSG, secrets from
.dev.vars
and local binding values are included in the static build. Be careful with sensitive data.
对于静态站点生成路由,使用异步模式:
typescript
// 在SSG路由中(如generateStaticParams等)
const { env } = await getCloudflareContext({ async: true });
const products = await env.DB.prepare("SELECT * FROM products").all();
警告:在SSG过程中,
.dev.vars
中的密钥和本地绑定值会被包含在静态构建产物中,请谨慎处理敏感数据。

TypeScript Types

TypeScript类型

Generate types for your bindings:
bash
npx wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts
Add to
package.json
:
json
{
  "scripts": {
    "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
  }
}
Run after any binding changes in
wrangler.jsonc
.
为绑定生成类型:
bash
npx wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts
package.json
添加脚本:
json
{
  "scripts": {
    "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
  }
}
wrangler.jsonc
中修改绑定后运行该脚本。

CLI Commands

CLI命令

The
opennextjs-cloudflare
CLI wraps Wrangler with OpenNext-specific behavior:
bash
undefined
opennextjs-cloudflare
CLI基于Wrangler封装,提供OpenNext专属功能:
bash
undefined

Build the Next.js app and transform for Workers

构建Next.js应用并转换为Workers适配格式

npx opennextjs-cloudflare build
npx opennextjs-cloudflare build

Build and preview locally with Wrangler

构建并通过Wrangler本地预览

npm run preview
npm run preview

or

npx opennextjs-cloudflare preview
npx opennextjs-cloudflare preview

Build and deploy to Cloudflare

构建并部署到Cloudflare

npm run deploy
npm run deploy

or

npx opennextjs-cloudflare deploy
npx opennextjs-cloudflare deploy

Build and upload as a version (doesn't deploy)

构建并上传为版本(不部署)

npm run upload
npm run upload

or

npx opennextjs-cloudflare upload
npx opennextjs-cloudflare upload

Populate cache (called automatically by preview/deploy/upload)

填充缓存(预览/部署/上传时自动调用)

npx opennextjs-cloudflare populateCache local # Local bindings npx opennextjs-cloudflare populateCache remote # Remote bindings

**Recommended package.json scripts**:

```json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
    "deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
    "upload": "opennextjs-cloudflare build && opennextjs-cloudflare upload",
    "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
  }
}
npx opennextjs-cloudflare populateCache local # 本地绑定 npx opennextjs-cloudflare populateCache remote # 远程绑定

**推荐的package.json脚本**:

```json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
    "deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
    "upload": "opennextjs-cloudflare build && opennextjs-cloudflare upload",
    "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
  }
}

Caching Strategies

缓存策略

OpenNext supports Next.js caching with Cloudflare storage:
Cache TypeUse CaseStorage Options
Incremental CacheISR/SSG page dataR2, KV, Static Assets
QueueTime-based revalidationDurable Objects, Memory
Tag CacheOn-demand revalidationD1, Durable Objects
Quick setup examples:
typescript
// Static Site (SSG only)
import staticAssetsCache from "@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache";
export default defineCloudflareConfig({
  incrementalCache: staticAssetsCache,
  enableCacheInterception: true,
});

// Small Site with ISR
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
export default defineCloudflareConfig({
  incrementalCache: r2IncrementalCache,
  queue: doQueue,
  tagCache: d1NextTagCache,
});
See references/caching.md for complete caching patterns including regional cache and sharded tag cache
OpenNext支持通过Cloudflare存储实现Next.js缓存:
缓存类型适用场景存储选项
增量缓存ISR/SSG页面数据R2、KV、静态资源
队列基于时间的重新验证Durable Objects、内存
标签缓存按需重新验证D1、Durable Objects
快速设置示例:
typescript
// 静态站点(仅SSG)
import staticAssetsCache from "@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache";
export default defineCloudflareConfig({
  incrementalCache: staticAssetsCache,
  enableCacheInterception: true,
});

// 带ISR的小型站点
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
export default defineCloudflareConfig({
  incrementalCache: r2IncrementalCache,
  queue: doQueue,
  tagCache: d1NextTagCache,
});
查看references/caching.md获取完整缓存模式,包括区域缓存和分片标签缓存

Image Optimization

图片优化

Enable Cloudflare Images for automatic image optimization:
jsonc
// wrangler.jsonc
{
  "images": {
    "binding": "IMAGES"
  }
}
Next.js
<Image>
components will automatically use Cloudflare Images. Additional costs apply.
Compatibility notes:
  • Supports: PNG, JPEG, WEBP, AVIF, GIF, SVG
  • minimumCacheTTL
    not supported
  • dangerouslyAllowLocalIP
    not supported
启用Cloudflare Images实现自动图片优化:
jsonc
// wrangler.jsonc
{
  "images": {
    "binding": "IMAGES"
  }
}
Next.js
<Image>
组件将自动使用Cloudflare Images。会产生额外费用。
兼容性说明:
  • 支持格式:PNG、JPEG、WEBP、AVIF、GIF、SVG
  • 不支持
    minimumCacheTTL
  • 不支持
    dangerouslyAllowLocalIP

Database and ORM Patterns

数据库与ORM模式

Critical Rule: Never create global database clients in Workers. Create per-request:
typescript
// ❌ WRONG - Global client causes I/O errors
import { Pool } from "pg";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });

// ✅ CORRECT - Per-request client
import { cache } from "react";
import { Pool } from "pg";

export const getDb = cache(() => {
  const pool = new Pool({
    connectionString: process.env.DATABASE_URL,
    maxUses: 1,  // Don't reuse connections across requests
  });
  return drizzle({ client: pool, schema });
});

// Usage in route
export async function GET() {
  const db = getDb();
  const users = await db.select().from(usersTable);
  return Response.json(users);
}
See references/database-orm.md for Drizzle and Prisma patterns.
关键规则:切勿在Workers中创建全局数据库客户端,应按请求创建:
typescript
// ❌ 错误 - 全局客户端会导致I/O错误
import { Pool } from "pg";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });

// ✅ 正确 - 按请求创建客户端
import { cache } from "react";
import { Pool } from "pg";

export const getDb = cache(() => {
  const pool = new Pool({
    connectionString: process.env.DATABASE_URL,
    maxUses: 1,  // 不要跨请求复用连接
  });
  return drizzle({ client: pool, schema });
});

// 在路由中使用
export async function GET() {
  const db = getDb();
  const users = await db.select().from(usersTable);
  return Response.json(users);
}
查看references/database-orm.md获取Drizzle和Prisma的配置模式。

Critical Rules

关键规则

✅ DO

✅ 建议

  1. Use Node.js runtime - Default runtime, remove any
    export const runtime = "edge"
  2. Create DB clients per-request - Use React's
    cache()
    for request-scoped instances
  3. Enable nodejs_compat - Required compatibility flag with date >= 2024-09-23
  4. Use getCloudflareContext() - Access bindings, not getRequestContext from next-on-pages
  5. Add .open-next to .gitignore - Build output should not be committed
  6. Use wrangler.jsonc - Not wrangler.toml (JSONC supports comments and validation)
  7. Set WORKER_SELF_REFERENCE - Service binding must match worker name
  8. Add public/_headers - Configure static asset caching headers
  1. 使用Node.js运行时 - 默认运行时,移除所有
    export const runtime = "edge"
    代码
  2. 按请求创建数据库客户端 - 使用React的
    cache()
    创建请求作用域的实例
  3. 启用nodejs_compat - 必需的兼容性标志,日期需大于等于2024-09-23
  4. 使用getCloudflareContext() - 访问绑定,而非next-on-pages中的getRequestContext
  5. 将.open-next添加到.gitignore - 构建产物无需提交到版本库
  6. 使用wrangler.jsonc - 不要使用wrangler.toml(JSONC支持注释和验证)
  7. 设置WORKER_SELF_REFERENCE - 服务绑定必须与Worker名称一致
  8. 添加public/_headers - 配置静态资源缓存头

❌ DON'T

❌ 禁止

  1. Don't use Edge runtime - Remove
    export const runtime = "edge"
    from all routes
  2. Don't use Turbopack - Use
    next build
    , not
    next build --turbo
  3. Don't create global DB clients - Causes "Cannot perform I/O" errors
  4. Don't exceed 10 MiB - Worker size limit (3 MiB on free plan)
  5. Don't use next-on-pages - Different adapter, use @opennextjs/cloudflare instead
  6. Don't commit .open-next/ - Build output directory
  7. Don't use Node Middleware - Not supported (Next.js 15.2+ feature)
  1. 不要使用Edge运行时 - 从所有路由中移除
    export const runtime = "edge"
  2. 不要使用Turbopack - 使用
    next build
    ,而非
    next build --turbo
  3. 不要创建全局数据库客户端 - 会导致"无法执行I/O"错误
  4. 不要超过10 MiB - Worker体积限制(免费计划为3 MiB)
  5. 不要使用next-on-pages - 这是不同的适配器,请使用@opennextjs/cloudflare
  6. 不要提交.open-next/ - 构建产物目录
  7. 不要使用Node Middleware - 不支持(Next.js 15.2+新增特性)

Supported Features

支持的特性

FeatureSupportNotes
App Router✅ FullAll features supported
Pages Router✅ FullIncluding API routes
Route Handlers✅ FullGET, POST, etc.
Dynamic Routes✅ Full
[slug]
,
[...slug]
SSG✅ FullStatic Site Generation
SSR✅ FullServer-Side Rendering
ISR✅ FullIncremental Static Regeneration
PPR✅ FullPartial Prerendering
Middleware✅ PartialStandard middleware works, Node Middleware (15.2+) not supported
Image Optimization✅ FullVia Cloudflare Images binding
Composable Caching✅ Full
'use cache'
directive
next/font✅ FullFont optimization
after()✅ FullBackground tasks
Turbopack❌ NoUse standard build
Supported Next.js versions:
  • Next.js 15: All minor and patch versions
  • Next.js 14: Latest minor version only
特性支持状态说明
App Router✅ 完全支持所有特性均支持
Pages Router✅ 完全支持包括API路由
路由处理器✅ 完全支持GET、POST等方法
动态路由✅ 完全支持
[slug]
[...slug]
SSG✅ 完全支持静态站点生成
SSR✅ 完全支持服务端渲染
ISR✅ 完全支持增量静态再生
PPR✅ 完全支持部分预渲染
中间件✅ 部分支持标准中间件可用,Node Middleware(15.2+)不支持
图片优化✅ 完全支持通过Cloudflare Images绑定实现
可组合缓存✅ 完全支持
'use cache'
指令
next/font✅ 完全支持字体优化
after()✅ 完全支持后台任务
Turbopack❌ 不支持使用标准构建命令
支持的Next.js版本:
  • Next.js 15: 所有小版本和补丁版本
  • Next.js 14: 仅最新小版本

Development Workflow

开发流程

bash
undefined
bash
undefined

Local development with Next.js dev server

使用Next.js开发服务器进行本地开发

npm run dev
npm run dev

Preview in Workers runtime (faster than deploy)

在Workers运行时中预览(比部署更快)

npm run preview
npm run preview

Deploy to production

部署到生产环境

npm run deploy
npm run deploy

Update TypeScript types after binding changes

修改绑定后更新TypeScript类型

npm run cf-typegen

**Local Development Notes**:
- `next dev` - Uses Node.js runtime, bindings available via `initOpenNextCloudflareForDev()`
- `npm run preview` - Uses Workers runtime with Wrangler, closer to production
- Both support hot reloading
npm run cf-typegen

**本地开发说明**:
- `next dev` - 使用Node.js运行时,通过`initOpenNextCloudflareForDev()`可访问绑定
- `npm run preview` - 使用Wrangler运行Workers运行时,更贴近生产环境
- 两者均支持热重载

Detailed References

详细参考文档

  • references/configuration.md - Complete wrangler.jsonc, environment variables, TypeScript types
  • references/caching.md - ISR, SSG, R2/KV/D1 caches, tag cache, queues, cache purge
  • references/database-orm.md - Drizzle, Prisma setup with D1, PostgreSQL, Hyperdrive
  • references/troubleshooting.md - Size limits, bundle analysis, common errors
  • references/configuration.md - 完整的wrangler.jsonc、环境变量、TypeScript类型配置
  • references/caching.md - ISR、SSG、R2/KV/D1缓存、标签缓存、队列、缓存清理
  • references/database-orm.md - Drizzle、Prisma与D1、PostgreSQL、Hyperdrive的配置
  • references/troubleshooting.md - 体积限制、包分析、常见错误

Migration from @cloudflare/next-on-pages

从@cloudflare/next-on-pages迁移

If migrating from
@cloudflare/next-on-pages
:
  1. Uninstall
    @cloudflare/next-on-pages
    and
    eslint-plugin-next-on-pages
  2. Install
    @opennextjs/cloudflare
  3. Update
    next.config.ts
    :
    • Remove
      setupDevPlatform()
      calls
    • Replace with
      initOpenNextCloudflareForDev()
  4. Update imports:
    • Replace
      getRequestContext
      from
      @cloudflare/next-on-pages
    • Use
      getCloudflareContext
      from
      @opennextjs/cloudflare
  5. Remove Edge runtime exports (
    export const runtime = "edge"
    )
  6. Update wrangler.jsonc with required OpenNext settings
  7. Remove next-on-pages eslint rules
若从
@cloudflare/next-on-pages
迁移:
  1. 卸载
    @cloudflare/next-on-pages
    eslint-plugin-next-on-pages
  2. 安装
    @opennextjs/cloudflare
  3. 更新
    next.config.ts
    :
    • 移除
      setupDevPlatform()
      调用
    • 替换为
      initOpenNextCloudflareForDev()
  4. 更新导入:
    • 替换
      @cloudflare/next-on-pages
      中的
      getRequestContext
    • 使用
      @opennextjs/cloudflare
      中的
      getCloudflareContext
  5. 移除Edge运行时导出(
    export const runtime = "edge"
  6. 更新wrangler.jsonc以添加OpenNext必需设置
  7. 移除next-on-pages的ESLint规则

Examples

示例

Official examples in the @opennextjs/cloudflare repository:
  • create-next-app
    - Basic Next.js starter
  • middleware
    - Middleware usage
  • vercel-blog-starter
    - SSG blog example
官方示例位于@opennextjs/cloudflare仓库
  • create-next-app
    - 基础Next.js启动模板
  • middleware
    - 中间件使用示例
  • vercel-blog-starter
    - SSG博客示例

Best Practices

最佳实践

  1. Start simple - Use Static Assets cache for SSG-only sites
  2. Add caching gradually - Enable R2 cache when you need ISR
  3. Monitor bundle size - Stay under 10 MiB compressed (use ESBuild Bundle Analyzer)
  4. Use TypeScript - Run
    cf-typegen
    to get binding types
  5. Test with preview - Use
    npm run preview
    before deploying
  6. Cache database clients - Use React's
    cache()
    for per-request instances
  7. Enable observability - Add
    observability
    to wrangler.jsonc for logging
  8. Use remote bindings for build - Enable for ISR with real data
  1. 从简单开始 - 仅SSG的站点使用静态资源缓存
  2. 逐步添加缓存 - 需要ISR时再启用R2缓存
  3. 监控包体积 - 保持压缩后体积在10 MiB以内(使用ESBuild Bundle Analyzer)
  4. 使用TypeScript - 运行
    cf-typegen
    获取绑定类型
  5. 预览后再部署 - 部署前使用
    npm run preview
    测试
  6. 缓存数据库客户端 - 使用React的
    cache()
    创建按请求实例
  7. 启用可观测性 - 在wrangler.jsonc中添加
    observability
    配置以启用日志
  8. 构建时使用远程绑定 - 为ISR启用真实数据访问

Common Patterns

常见模式

See references/configuration.md for complete examples including:
  • Custom Worker with multiple handlers (fetch, scheduled, queue)
  • Environment-specific configuration (staging, production)
  • Remote bindings for build-time data access
查看references/configuration.md获取完整示例,包括:
  • 带多个处理器的自定义Worker(fetch、scheduled、queue)
  • 环境专属配置( staging、production)
  • 构建时数据访问的远程绑定

Resources

资源