From d235af4673d227f278d15c2d3d2c7a1384a2cf4f Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Tue, 24 Sep 2024 12:13:52 +0100 Subject: [PATCH 01/20] Add docs for Cloudflare adapter --- pages/aws/index.mdx | 2 +- pages/cloudflare/bindings.mdx | 85 ++++++++++++++++++++++++++++++++ pages/cloudflare/caching.mdx | 6 +++ pages/cloudflare/get_started.mdx | 80 ++++++++++++++++++++++++++++++ pages/cloudflare/index.mdx | 54 +++++++++++++++++++- pages/index.mdx | 6 +-- 6 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 pages/cloudflare/bindings.mdx create mode 100644 pages/cloudflare/caching.mdx create mode 100644 pages/cloudflare/get_started.mdx diff --git a/pages/aws/index.mdx b/pages/aws/index.mdx index b6fdb6a..44ec1d4 100644 --- a/pages/aws/index.mdx +++ b/pages/aws/index.mdx @@ -13,7 +13,7 @@ If you're migrating from V2 to V3, you can find the migration guide [here](/migr --- OpenNext takes the Next.js build output and converts it into packages that can be deployed across a variety of environments. -Natively OpenNext has support for AWS Lambda and classic Node Server. It also offer partial support for the `edge` runtime in Cloudflare Workers. +Natively OpenNext has support for AWS Lambda, [Cloudflare](/cloudflare), and classic Node.js Server. One notable feature of OpenNext is its ability to split the Next.js output, enabling selective deployment to different targets such as AWS Lambda, Cloudflare Workers, or Amazon ECS. This facilitates a tailored deployment strategy that aligns with the specific needs of your application. diff --git a/pages/cloudflare/bindings.mdx b/pages/cloudflare/bindings.mdx new file mode 100644 index 0000000..8675a81 --- /dev/null +++ b/pages/cloudflare/bindings.mdx @@ -0,0 +1,85 @@ +import { SITE } from '../../config'; +import { Callout } from 'nextra/components'; + +### Bindings + +[Bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) allow your Worker to interact with resources on the Cloudflare Developer Platform. When you declare a binding on your Worker, you grant it a specific capability, such as being able to read and write files to an [R2](https://developers.cloudflare.com/r2/) bucket. + + +If your app uses both bindings and @opennextjs/cloudflare, you currently cannot access bindings when running `next dev`. Instead, you must build your app using @opennextjs/cloudflare and then run it locally in the Workers runtime as described [here](/cloudflare/get-started). This means you cannot use hot-module reloading (HMR) for a faster development workflow. @opennextjs/cloudflare is pre 1.0, in active development, and we plan to address this soon. + +Alternatively, you can use [@cloudflare/next-on-pages](https://www.npmjs.com/package/@cloudflare/next-on-pages) to deploy Next.js apps to Cloudflare Pages. You can review the differences in supported Next.js features between @opennextjs/cloudflare and @cloudflare/next-on-pages [here](LINK). + + +#### How to configure your Next.js app so it can access bindings + +Install [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare), and then add a `wrangler.toml` file in the root directory of your Next.js app, as described in [Get Started](/cloudflare/get-started), y + +#### How to access bindings in your Next.js app + +You can access [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) from any route of your Next.js app via `getRequestContext`: + +```js +// TODO: possible to bring this in from next-on-pages? +import { getRequestContext } from "@cloudflare/next-on-pages"; + +export async function GET(request) { + let responseText = "Hello World"; + + const myKv = getRequestContext().env.MY_KV_NAMESPACE; + await myKv.put("foo", "bar"); + const foo = await myKv.get("foo"); + + return new Response(foo); +} +``` + +#### How to add bindings to your Worker + +Add bindings to your Worker by [adding them to your `wrangler.toml` configuration file](/pages/functions/wrangler-configuration/). + +## TypeScript type declarations for bindings + +To ensure that the `env` object from `getRequestContext().env` above has accurate TypeScript types, install [`@cloudflare/workers-types`](https://www.npmjs.com/package/@cloudflare/workers-types) and create a [TypeScript declaration file](https://www.typescriptlang.org/docs/handbook/2/type-declarations.html). + +Install Workers Types: + +```sh +npm install --save-dev @cloudflare/workers-types +``` + +Add Workers Types to your `tsconfig.json` file, replacing the date below with your project's [compatibility date](https://developers.cloudflare.com/workers/configuration/compatibility-dates/): + +```diff title="tsconfig.json" + "types": [ ++ "@cloudflare/workers-types/2024-07-29" + ] +``` + +Create an `env.d.ts` file in the root directory of your Next.js app, and explicitly declare the type of each binding: + +```ts title="env.d.ts" +interface CloudflareEnv { + MY_KV_1: KVNamespace; + MY_KV_2: KVNamespace; + MY_R2: R2Bucket; + MY_DO: DurableObjectNamespace; +} +``` + +## Other Cloudflare APIs (`cf`, `ctx`) + +You can access context about the incoming request from the [`cf` object](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties), as well as [lifecycle methods from the `ctx` object](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/#lifecycle-methods) from the return value of [`getRequestContext()`](https://github.com/cloudflare/next-on-pages/blob/main/packages/next-on-pages/src/api/getRequestContext.ts): + +```js +// TODO: possible to bring this in from next-on-pages? +import { getRequestContext } from "@cloudflare/next-on-pages"; + +export const runtime = "edge"; + +export async function GET(request) { + const { env, cf, ctx } = getRequestContext(); + + // ... +} +``` diff --git a/pages/cloudflare/caching.mdx b/pages/cloudflare/caching.mdx new file mode 100644 index 0000000..57e6950 --- /dev/null +++ b/pages/cloudflare/caching.mdx @@ -0,0 +1,6 @@ +import { SITE } from '../../config'; +import { Callout } from 'nextra/components'; + +## Caching + +TODO \ No newline at end of file diff --git a/pages/cloudflare/get_started.mdx b/pages/cloudflare/get_started.mdx new file mode 100644 index 0000000..0dcfa3f --- /dev/null +++ b/pages/cloudflare/get_started.mdx @@ -0,0 +1,80 @@ +import { SITE } from '../../config'; +import { Callout } from 'nextra/components'; + +### Get Started + +#### New apps + +To create a new Next.js app, pre-configured to run on Cloudflare using @opennextjs/cloudflare, run: + +``` + +``` + +#### Existing Next.js apps + +##### 1. Install @cloudflare/next-on-pages + +First, install [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare): + +```sh +npm install --save-dev @opennextjs/cloudflare +``` + +##### 2. Add a `wrangler.toml` file + +Then, add a [`wrangler.toml`](https://developers.cloudflare.com/workers/wrangler/configuration/) file to the root directory of your Next.js app: + +```toml +name = "my-app" +compatibility_date = "2024-07-29" +compatibility_flags = ["nodejs_compat"] +assets = { directory = "public"} +``` + +`wrangler.toml` is where you configure your Worker and define what resources it can access via [bindings](/workers/runtime-apis/bindings/). + +##### 3. Update `next.config.mjs` + +Next, update the content in your `next.config.mjs` file. + +```diff title="next.config.mjs" ++ import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev'; + +/** @type {import('next').NextConfig} */ +const nextConfig = {}; + ++ if (process.env.NODE_ENV === 'development') { ++ await setupDevPlatform(); ++ } + +export default nextConfig; +``` + +These changes allows you to access [bindings](/pages/framework-guides/nextjs/ssr/bindings/) in local development. + +##### 5. Update `package.json` + +Add the following to the scripts field of your `package.json` file: + +```json title="package.json" +"build:worker": "cloudflare", TODO +"dev:worker": "wrangler dev --port 8771", +"preview:worker": "npm run build:worker && npm run dev:worker", +"deploy:worker": "npm run build:worker && wrangler deploy" +``` + +- `npm run build:worker`: Runs the [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) adapter. This first builds your app by running `next build` behind the scenes, and then transforms the build output to a format that you can run locally using [Wrangler](https://developers.cloudflare.com/workers/wrangler/), and deploy to Cloudflare. +- `npm run dev:worker`: Takes the output generated by `build:worker` and runs it locally in [workerd](https://github.com/cloudflare/workerd), the open-source Workers Runtime, allowing you to run the app locally in the same environment that it will run in production. If you instead run `next dev`, your app will run in Node.js, which is a different JavaScript runtime from the Workers runtime, with differences in behavior and APIs. +- `npm run preview:worker`: Runs `build:worker` and then `preview:worker`, allowing you to quickly preview your app running locally in the Workers runtime, via a single command. +- `npm run deploy`: Builds your app, and then deploys it to Cloudflare + +##### 6. Deploy to Cloudflare Workers + +Either deploy via the command line: + +```sh +npm run deploy +``` + +Or [connect a Github or Gitlab repository](https://develoers.cloudflare.com/workers/ci-cd/), and Cloudflare will automatically build and deploy each pull request you merge to your production branch. \ No newline at end of file diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx index d8599ae..e5dddc0 100644 --- a/pages/cloudflare/index.mdx +++ b/pages/cloudflare/index.mdx @@ -1,2 +1,54 @@ -### TODO +import { SITE } from '../../config'; +import { Callout } from 'nextra/components'; +## Cloudflare + +--- + +The [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) adapter lets you deploy Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers) and [Cloudflare Pages](https://developers.cloudflare.com/pages). + +--- + + +[@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) is pre 1.0, and still in active development. You should try it, [report bugs](https://github.com/opennextjs/opennextjs-cloudflare/issues), and [share feedback](https://github.com/opennextjs/opennextjs-cloudflare/discussions) to help make running Next.js apps on Cloudflare easier. We don't quite yet recommend using it for mission-critical production apps. + +You can also use [@cloudflare/next-on-pages](https://www.npmjs.com/package/@cloudflare/next-on-pages) to deploy Next.js apps to Cloudflare Pages. You can review the differences in supported Next.js features between @opennextjs/cloudflare and @cloudflare/next-on-pages [here](LINK). + + +### Get Started + +##### New apps + +To create a new Next.js app, pre-configured to run on Cloudflare using @opennextjs/cloudflare, run: + +``` + +``` + +##### Existing Next.js apps + +Follow the guide [here](/cloudflare/get-started) to use [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) with an existing Next.js app. + +### Supported Next.js features + +TODO: Check these, what else should / shouldn't be on here + +- [x] App & Pages Router +- [x] API routes +- [x] Dynamic routes +- [x] Static site generation (SSG) +- [x] Server-side rendering (SSR) +- [x] Incremental static regeneration (ISR) +- [x] Partial Prerendering (PPR) +- [x] Middleware +- [x] Image optimization +- [ ] [NextAuth.js](https://next-auth.js.org) +- [x] Experimental streaming support + +### How @opennextjs/cloudflare Works + +The OpenNext Cloudflare adapter works by taking the Next.js build output and transforming it, so that it can run in Cloudflare Workers. + +When you add [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) as a dependency to your Next.js app, and then run `pnpx cloudflare` (TODO: why pnpx?), the adapter first builds your app by running `next build`, and then transforms the build output to a format that you can run locally using [Wrangler](https://developers.cloudflare.com/workers/wrangler/), and deploy to Cloudflare. + +You can view the code for @opennextjs/cloudflare [here](https://github.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src) to understand what it does under the hood. \ No newline at end of file diff --git a/pages/index.mdx b/pages/index.mdx index c05216f..d393a77 100644 --- a/pages/index.mdx +++ b/pages/index.mdx @@ -2,7 +2,7 @@ import { SITE } from '../config'; # OpenNext -Next.js, unlike Remix, Astro, or the other modern frontends, doesn't have a way to self-host across different platforms. You can run it as a Node application. But this doesn't work the same way as it does on Vercel. +Next.js, unlike Remix, Astro, or the other modern frontends, doesn't have a way to self-host across different platforms. You can run it as a Node.js application. But this doesn't work the same way as it does on Vercel. --- @@ -14,10 +14,10 @@ OpenNext is an initiative to bring all these efforts together. --- -OpenNext is currently backed by. +OpenNext is currently backed by: 1. [SST](https://sst.dev) community, maintains the [AWS](aws) adapter -2. [Cloudflare](https://www.cloudflare.com) team, maintains the [Cloudflare](cloudflare) adapter +2. [Cloudflare](https://developers.cloudflare.com/) team, maintains the [Cloudflare](cloudflare) adapter 3. [Netlify](http://netlify.com) team, maintains the [Netlify](netlify) adapter If you'd like to join the effort, connect with us on [Discord](https://discord.gg/opennextjs). From 9cfb8271c0952c89c28fa8366061a4c93b4ec65a Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Tue, 24 Sep 2024 12:59:52 +0100 Subject: [PATCH 02/20] Fixes --- pages/cloudflare/{get_started.mdx => get-started.mdx} | 0 pages/cloudflare/index.mdx | 4 ---- 2 files changed, 4 deletions(-) rename pages/cloudflare/{get_started.mdx => get-started.mdx} (100%) diff --git a/pages/cloudflare/get_started.mdx b/pages/cloudflare/get-started.mdx similarity index 100% rename from pages/cloudflare/get_started.mdx rename to pages/cloudflare/get-started.mdx diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx index e5dddc0..8502a6b 100644 --- a/pages/cloudflare/index.mdx +++ b/pages/cloudflare/index.mdx @@ -3,12 +3,8 @@ import { Callout } from 'nextra/components'; ## Cloudflare ---- - The [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) adapter lets you deploy Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers) and [Cloudflare Pages](https://developers.cloudflare.com/pages). ---- - [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) is pre 1.0, and still in active development. You should try it, [report bugs](https://github.com/opennextjs/opennextjs-cloudflare/issues), and [share feedback](https://github.com/opennextjs/opennextjs-cloudflare/discussions) to help make running Next.js apps on Cloudflare easier. We don't quite yet recommend using it for mission-critical production apps. From a9b878e49de821fe87b93b3b6e3c25c840fc4715 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Tue, 24 Sep 2024 13:03:10 +0100 Subject: [PATCH 03/20] Callout nodejs_compat instructions more explicitly --- pages/cloudflare/get-started.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx index 0dcfa3f..cf11928 100644 --- a/pages/cloudflare/get-started.mdx +++ b/pages/cloudflare/get-started.mdx @@ -27,11 +27,15 @@ Then, add a [`wrangler.toml`](https://developers.cloudflare.com/workers/wrangler ```toml name = "my-app" -compatibility_date = "2024-07-29" +compatibility_date = "2024-09-23" compatibility_flags = ["nodejs_compat"] assets = { directory = "public"} ``` + +As shown above, you must enable the [`nodejs_compat` compatibility flag](https://developers.cloudflare.com/workers/runtime-apis/nodejs/) *and* set your [compatibility date](https://developers.cloudflare.com/workers/configuration/compatibility-dates/) to `2024-09-23` or later, in order for your Next.js app to work with @opennextjs/cloudflare. + + `wrangler.toml` is where you configure your Worker and define what resources it can access via [bindings](/workers/runtime-apis/bindings/). ##### 3. Update `next.config.mjs` From 1ccc2cfa1bf9f89a6cefe6ba4e43329344ece873 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Tue, 24 Sep 2024 13:11:06 +0100 Subject: [PATCH 04/20] Add basic examples page --- pages/cloudflare/examples.mdx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 pages/cloudflare/examples.mdx diff --git a/pages/cloudflare/examples.mdx b/pages/cloudflare/examples.mdx new file mode 100644 index 0000000..163c7c3 --- /dev/null +++ b/pages/cloudflare/examples.mdx @@ -0,0 +1,19 @@ +import { SITE } from '../../config'; +import { Callout } from 'nextra/components'; + +## Examples + +### Basic starter projects + +Two basic example apps are included in the repository for `@opennextjs/cloudflare` package: + +- [*`create-next-app`*](https://github.com/opennextjs/opennextjs-cloudflare/tree/main/examples/create-next-app) — a Next.js project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). +- [*`api`*](https://github.com/opennextjs/opennextjs-cloudflare/tree/main/examples/api) — a minimal Next.js project with a single API route + +You can use these to understand how to configure your Next.js app to use `@opennextjs/cloudflare`, or refer to [Get Started](/cloudflare/get-started). + +### Next.js Commerce Demo + +The [Next.js Commerce demo app](https://github.com/vercel/commerce/tree/v1) works with `@opennextjs/cloudflare`. You can view a deployed version of it [here](TODO). + +To run this using `@opennextjs/cloudflare`, TODO. \ No newline at end of file From b43fd26d936994569e865661c7b3ad75653dfb32 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Tue, 24 Sep 2024 14:10:59 +0100 Subject: [PATCH 05/20] Fix unnecessary content --- pages/cloudflare/get-started.mdx | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx index cf11928..403e8fc 100644 --- a/pages/cloudflare/get-started.mdx +++ b/pages/cloudflare/get-started.mdx @@ -26,10 +26,11 @@ npm install --save-dev @opennextjs/cloudflare Then, add a [`wrangler.toml`](https://developers.cloudflare.com/workers/wrangler/configuration/) file to the root directory of your Next.js app: ```toml +main = ".worker-next/index.mjs" name = "my-app" compatibility_date = "2024-09-23" compatibility_flags = ["nodejs_compat"] -assets = { directory = "public"} +experimental_assets = { directory = ".worker-next/assets", binding = "ASSETS" } ``` @@ -38,26 +39,7 @@ As shown above, you must enable the [`nodejs_compat` compatibility flag](https:/ `wrangler.toml` is where you configure your Worker and define what resources it can access via [bindings](/workers/runtime-apis/bindings/). -##### 3. Update `next.config.mjs` - -Next, update the content in your `next.config.mjs` file. - -```diff title="next.config.mjs" -+ import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev'; - -/** @type {import('next').NextConfig} */ -const nextConfig = {}; - -+ if (process.env.NODE_ENV === 'development') { -+ await setupDevPlatform(); -+ } - -export default nextConfig; -``` - -These changes allows you to access [bindings](/pages/framework-guides/nextjs/ssr/bindings/) in local development. - -##### 5. Update `package.json` +##### 3. Update `package.json` Add the following to the scripts field of your `package.json` file: @@ -73,7 +55,7 @@ Add the following to the scripts field of your `package.json` file: - `npm run preview:worker`: Runs `build:worker` and then `preview:worker`, allowing you to quickly preview your app running locally in the Workers runtime, via a single command. - `npm run deploy`: Builds your app, and then deploys it to Cloudflare -##### 6. Deploy to Cloudflare Workers +##### 4. Deploy to Cloudflare Workers Either deploy via the command line: @@ -81,4 +63,4 @@ Either deploy via the command line: npm run deploy ``` -Or [connect a Github or Gitlab repository](https://develoers.cloudflare.com/workers/ci-cd/), and Cloudflare will automatically build and deploy each pull request you merge to your production branch. \ No newline at end of file +Or [connect a Github or Gitlab repository](https://developers.cloudflare.com/workers/ci-cd/), and Cloudflare will automatically build and deploy each pull request you merge to your production branch. \ No newline at end of file From 05933a816fbbddc1f43fa5f8ccdc7c161e703c39 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Tue, 24 Sep 2024 14:24:46 +0100 Subject: [PATCH 06/20] Add links --- pages/cloudflare/index.mdx | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx index 8502a6b..d7d56e0 100644 --- a/pages/cloudflare/index.mdx +++ b/pages/cloudflare/index.mdx @@ -3,7 +3,7 @@ import { Callout } from 'nextra/components'; ## Cloudflare -The [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) adapter lets you deploy Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers) and [Cloudflare Pages](https://developers.cloudflare.com/pages). +The [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) adapter lets you deploy Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers) and [Cloudflare Pages](https://developers.cloudflare.com/pages), using the [Node.js "runtime" from Next.js](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes). [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) is pre 1.0, and still in active development. You should try it, [report bugs](https://github.com/opennextjs/opennextjs-cloudflare/issues), and [share feedback](https://github.com/opennextjs/opennextjs-cloudflare/discussions) to help make running Next.js apps on Cloudflare easier. We don't quite yet recommend using it for mission-critical production apps. @@ -25,21 +25,28 @@ To create a new Next.js app, pre-configured to run on Cloudflare using @opennext Follow the guide [here](/cloudflare/get-started) to use [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) with an existing Next.js app. +### Supported Next.js runtimes + +Next.js has [two "runtimes"](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) — "Edge" and "Node.js". When you use `@opennextjs/cloudflare`, your app can use the Node.js runtime, which is more fully featured, and allows you to use the [Node.js APIs](/workers/runtime-apis/nodejs/) that are provided by the Cloudflare Workers runtime. + +This is an important difference from `@cloudflare/next-on-pages`, which only supports the "Edge" runtime. The Edge Runtime code in Next.js [intentionally constrains which APIs from Node.js can be used](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/plugins/middleware-plugin.ts#L820), and the "Edge" runtime does not support all Next.js features. + ### Supported Next.js features -TODO: Check these, what else should / shouldn't be on here - -- [x] App & Pages Router -- [x] API routes -- [x] Dynamic routes -- [x] Static site generation (SSG) -- [x] Server-side rendering (SSR) -- [x] Incremental static regeneration (ISR) -- [x] Partial Prerendering (PPR) -- [x] Middleware -- [x] Image optimization +- [x] [App Router](https://nextjs.org/docs/app) & [Pages Router](https://nextjs.org/docs/pages) +- [x] [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) +- [x] [Dynamic routes](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes) +- [x] [Static Site Generation (SSG)](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) +- [x] [Server-Side Rendering (SSR)](https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering) +- [x] [Incremental Static Regeneration (ISR)](https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration) + +### Not Yet Supported Next.js features + +- [ ] [Partial Prerendering (PPR)](https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering) +- [ ] [Middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware) +- [ ] [Image optimization](https://nextjs.org/docs/pages/building-your-application/optimizing/images) (you can integrate Cloudflare Images with Next.js by following [this guide](https://developers.cloudflare.com/images/transform-images/integrate-with-frameworks/)) - [ ] [NextAuth.js](https://next-auth.js.org) -- [x] Experimental streaming support +- [ ] [Experimental streaming support](https://nextjs.org/blog/next-15-rc#executing-code-after-a-response-with-nextafter-experimental) ### How @opennextjs/cloudflare Works From b30aec3200f8db384847488a1d689ec90867a8c7 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 02:23:21 +0100 Subject: [PATCH 07/20] Apply suggestions from code review Co-authored-by: Dario Piotrowicz --- pages/cloudflare/bindings.mdx | 14 ++++++-------- pages/cloudflare/get-started.mdx | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/pages/cloudflare/bindings.mdx b/pages/cloudflare/bindings.mdx index 8675a81..0c3a9df 100644 --- a/pages/cloudflare/bindings.mdx +++ b/pages/cloudflare/bindings.mdx @@ -17,7 +17,7 @@ Install [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloud #### How to access bindings in your Next.js app -You can access [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) from any route of your Next.js app via `getRequestContext`: +You can access [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) from any route of your Next.js app via `getCloudlfareContext`: ```js // TODO: possible to bring this in from next-on-pages? @@ -26,7 +26,7 @@ import { getRequestContext } from "@cloudflare/next-on-pages"; export async function GET(request) { let responseText = "Hello World"; - const myKv = getRequestContext().env.MY_KV_NAMESPACE; + const myKv = (await getCloudflareContext()).env.MY_KV_NAMESPACE; await myKv.put("foo", "bar"); const foo = await myKv.get("foo"); @@ -40,7 +40,7 @@ Add bindings to your Worker by [adding them to your `wrangler.toml` configuratio ## TypeScript type declarations for bindings -To ensure that the `env` object from `getRequestContext().env` above has accurate TypeScript types, install [`@cloudflare/workers-types`](https://www.npmjs.com/package/@cloudflare/workers-types) and create a [TypeScript declaration file](https://www.typescriptlang.org/docs/handbook/2/type-declarations.html). +To ensure that the `env` object from `(await getCloudflareContext()).env` above has accurate TypeScript types, install [`@cloudflare/workers-types`](https://www.npmjs.com/package/@cloudflare/workers-types) and create a [TypeScript declaration file](https://www.typescriptlang.org/docs/handbook/2/type-declarations.html). Install Workers Types: @@ -69,16 +69,14 @@ interface CloudflareEnv { ## Other Cloudflare APIs (`cf`, `ctx`) -You can access context about the incoming request from the [`cf` object](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties), as well as [lifecycle methods from the `ctx` object](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/#lifecycle-methods) from the return value of [`getRequestContext()`](https://github.com/cloudflare/next-on-pages/blob/main/packages/next-on-pages/src/api/getRequestContext.ts): +You can access context about the incoming request from the [`cf` object](https://developers.cloudflare.com/workers/runtime-apis/request/#the-cf-property-requestinitcfproperties), as well as lifecycle methods from the [`ctx` object](https://developers.cloudflare.com/workers/runtime-apis/context) from the return value of [`getCloudflareContext()`](https://github.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src/api/get-cloudflare-context.ts): ```js -// TODO: possible to bring this in from next-on-pages? -import { getRequestContext } from "@cloudflare/next-on-pages"; +import { getCloudflareContext } from "@opennextjs/cloudflare"; -export const runtime = "edge"; export async function GET(request) { - const { env, cf, ctx } = getRequestContext(); + const { env, cf, ctx } = await getCloudflareContext(); // ... } diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx index 403e8fc..e3c80f2 100644 --- a/pages/cloudflare/get-started.mdx +++ b/pages/cloudflare/get-started.mdx @@ -13,7 +13,7 @@ To create a new Next.js app, pre-configured to run on Cloudflare using @opennext #### Existing Next.js apps -##### 1. Install @cloudflare/next-on-pages +##### 1. Install @opennextjs/cloudflare First, install [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare): From 4abab8f03280bf8ef0a2de29cd693aac69cd41a7 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 08:02:40 +0100 Subject: [PATCH 08/20] Add troubleshooting page --- pages/cloudflare/troubleshooting.mdx | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 pages/cloudflare/troubleshooting.mdx diff --git a/pages/cloudflare/troubleshooting.mdx b/pages/cloudflare/troubleshooting.mdx new file mode 100644 index 0000000..3c939cf --- /dev/null +++ b/pages/cloudflare/troubleshooting.mdx @@ -0,0 +1,28 @@ +import { SITE } from '../../config'; +import { Callout } from 'nextra/components'; + +## Troubleshooting + +### My app fails to build when I import a specific NPM package + +First, make sure that the `nodejs_compat` compatibility flag is enabled, and your compatibility date is set to on or after "2024-09-23", in your `wrangler.toml` file. [Refer to the Workers docs](https://developers.cloudflare.com/workers/runtime-apis/nodejs/) for more details on Node.js support in Cloudflare Workers. + +Some NPM packages define multiple exports. For example: + +``` +"exports": { + "other": "./src/other.js", + "node": "./src/node.js", + "browser": "./src/browser.js", + "default": "./src/default.js" +}, +``` + +When you use `@opennextjs/cloudflare`, [Wrangler](https://developers.cloudflare.com/workers/wrangler/) bundles your code before running it locally, or deploying it to Cloudflare. Wrangler has to choose which export to use, when you import a module. By default, Wrangler, which uses [esbuild](https://esbuild.github.io/), handles this in a way that is not compatible with some NPM packages. + +You may want to modify how Wrangler resolves multiple exports, such that when you import packages, the `node` export, if present, is used. You can do do by defining the following variables in a `.env` file within the root directory of your Next.js app: + +``` +WRANGLER_BUILD_CONDITIONS="" +WRANGLER_BUILD_PLATFORM="node" +``` From c33a2b090a63ddddf036a1a12cb41d4572068bd6 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 08:22:01 +0100 Subject: [PATCH 09/20] Add caching sections --- pages/cloudflare/caching.mdx | 34 +++++++++++++++++++++++++++++++- pages/cloudflare/get-started.mdx | 28 ++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/pages/cloudflare/caching.mdx b/pages/cloudflare/caching.mdx index 57e6950..7e6c0b4 100644 --- a/pages/cloudflare/caching.mdx +++ b/pages/cloudflare/caching.mdx @@ -3,4 +3,36 @@ import { Callout } from 'nextra/components'; ## Caching -TODO \ No newline at end of file +`@opennextjs/cloudflare` supports [caching](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data) and [revalidating](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data) data returned by subrequests you make in your app by calling [`fetch()`](https://developers.cloudflare.com/workers/runtime-apis/fetch/). + +By default, all `fetch()` subrequests made in your Next.js app are cached. Refer to the [Next.js documentation](https://nextjs.org/docs/app/building-your-application/caching#opting-out-1) for information about how to disable caching for an individual subrequest, or for an entire route. + +[The cache persists across deployments](https://nextjs.org/docs/app/building-your-application/caching#data-cache). You are responsible for revalidating/purging this cache. + +:::note +Workers KV is eventually consistent, which means that it can take up to 60 seconds for updates to be reflected globally, when using the default TTL of 60 seconds. +::: + +### How to enable caching + +`opennextjs/cloudflare` uses [Workers KV](https://developers.cloudflare.com/kv/) as the cache for your Next.js app. Workers KV is [fast](https://blog.cloudflare.com/faster-workers-kv) and uses Cloudflare's [Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) to increase cache hit rates. When you write cached data to Workers KV, you write to storage that can be read by any Cloudflare location. This means your app can fetch data, cache it in KV, and then subsequent requests anywhere around the world can read from this cache. + +To enable caching, you must: + +#### 1. Create a KV namespace + +``` +npx wrangler@latest kv namespace create NEXT_CACHE_WORKERS_KV +``` + +#### 2. Add the KV namespace to your Worker + +``` +[[kv_namespaces]] +binding = "NEXT_CACHE_WORKERS_KV" +id = "" +``` + +### 3. Set the name of the binding to `NEXT_CACHE_WORKERS_KV` + +As shown above, the name of the binding that you configure for the KV namespace must be set to `NEXT_CACHE_WORKERS_KV`. \ No newline at end of file diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx index e3c80f2..c744fb9 100644 --- a/pages/cloudflare/get-started.mdx +++ b/pages/cloudflare/get-started.mdx @@ -43,7 +43,7 @@ As shown above, you must enable the [`nodejs_compat` compatibility flag](https:/ Add the following to the scripts field of your `package.json` file: -```json title="package.json" +```json "build:worker": "cloudflare", TODO "dev:worker": "wrangler dev --port 8771", "preview:worker": "npm run build:worker && npm run dev:worker", @@ -55,7 +55,31 @@ Add the following to the scripts field of your `package.json` file: - `npm run preview:worker`: Runs `build:worker` and then `preview:worker`, allowing you to quickly preview your app running locally in the Workers runtime, via a single command. - `npm run deploy`: Builds your app, and then deploys it to Cloudflare -##### 4. Deploy to Cloudflare Workers +### 4. Add caching with Workers KV + +`opennextjs/cloudflare` uses [Workers KV](https://developers.cloudflare.com/kv/) as the cache for your Next.js app. Workers KV is [fast](https://blog.cloudflare.com/faster-workers-kv) and uses Cloudflare's [Tiered Cache](https://developers.cloudflare.com/cache/how-to/tiered-cache/) to increase cache hit rates. When you write cached data to Workers KV, you write to storage that can be read by any Cloudflare location. This means your app can fetch data, cache it in KV, and then subsequent requests anywhere around the world can read from this cache. + +To enable caching, you must: + +##### Create a KV namespace + +``` +npx wrangler@latest kv namespace create NEXT_CACHE_WORKERS_KV +``` + +##### Add the KV namespace to your Worker + +``` +[[kv_namespaces]] +binding = "NEXT_CACHE_WORKERS_KV" +id = "" +``` + +#### Set the name of the binding to `NEXT_CACHE_WORKERS_KV` + +As shown above, the name of the binding that you configure for the KV namespace must be set to `NEXT_CACHE_WORKERS_KV`. + +##### 5. Deploy to Cloudflare Workers Either deploy via the command line: From 76c3b9a2560dcc1292bb8eb42eaff23d0572c2f4 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 08:24:04 +0100 Subject: [PATCH 10/20] Add npm create cloudflare command --- pages/cloudflare/get-started.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx index c744fb9..5499198 100644 --- a/pages/cloudflare/get-started.mdx +++ b/pages/cloudflare/get-started.mdx @@ -8,7 +8,7 @@ import { Callout } from 'nextra/components'; To create a new Next.js app, pre-configured to run on Cloudflare using @opennextjs/cloudflare, run: ``` - +npm create cloudflare@latest --no-auto-update --experimental --framework next ``` #### Existing Next.js apps From 523a9016687c945a75c73888050437493195eb39 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 08:25:19 +0100 Subject: [PATCH 11/20] Add npm create cloudflare command to examples page --- pages/cloudflare/examples.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pages/cloudflare/examples.mdx b/pages/cloudflare/examples.mdx index 163c7c3..77ea3b3 100644 --- a/pages/cloudflare/examples.mdx +++ b/pages/cloudflare/examples.mdx @@ -3,6 +3,12 @@ import { Callout } from 'nextra/components'; ## Examples +To create a new Next.js app, pre-configured to run on Cloudflare using @opennextjs/cloudflare, run: + +``` +npm create cloudflare@latest --no-auto-update --experimental --framework next +``` + ### Basic starter projects Two basic example apps are included in the repository for `@opennextjs/cloudflare` package: From ed1e429ecfd76f371fac3f0f17774d8cf93d6f89 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 08:29:53 +0100 Subject: [PATCH 12/20] Use --experimental-include-runtime --- pages/cloudflare/bindings.mdx | 38 +++++++++-------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/pages/cloudflare/bindings.mdx b/pages/cloudflare/bindings.mdx index 0c3a9df..86b5555 100644 --- a/pages/cloudflare/bindings.mdx +++ b/pages/cloudflare/bindings.mdx @@ -5,12 +5,6 @@ import { Callout } from 'nextra/components'; [Bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) allow your Worker to interact with resources on the Cloudflare Developer Platform. When you declare a binding on your Worker, you grant it a specific capability, such as being able to read and write files to an [R2](https://developers.cloudflare.com/r2/) bucket. - -If your app uses both bindings and @opennextjs/cloudflare, you currently cannot access bindings when running `next dev`. Instead, you must build your app using @opennextjs/cloudflare and then run it locally in the Workers runtime as described [here](/cloudflare/get-started). This means you cannot use hot-module reloading (HMR) for a faster development workflow. @opennextjs/cloudflare is pre 1.0, in active development, and we plan to address this soon. - -Alternatively, you can use [@cloudflare/next-on-pages](https://www.npmjs.com/package/@cloudflare/next-on-pages) to deploy Next.js apps to Cloudflare Pages. You can review the differences in supported Next.js features between @opennextjs/cloudflare and @cloudflare/next-on-pages [here](LINK). - - #### How to configure your Next.js app so it can access bindings Install [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare), and then add a `wrangler.toml` file in the root directory of your Next.js app, as described in [Get Started](/cloudflare/get-started), y @@ -20,8 +14,7 @@ Install [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloud You can access [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) from any route of your Next.js app via `getCloudlfareContext`: ```js -// TODO: possible to bring this in from next-on-pages? -import { getRequestContext } from "@cloudflare/next-on-pages"; +import { getCloudflareContext } from "@cloudflare/next-on-pages"; export async function GET(request) { let responseText = "Hello World"; @@ -40,33 +33,22 @@ Add bindings to your Worker by [adding them to your `wrangler.toml` configuratio ## TypeScript type declarations for bindings -To ensure that the `env` object from `(await getCloudflareContext()).env` above has accurate TypeScript types, install [`@cloudflare/workers-types`](https://www.npmjs.com/package/@cloudflare/workers-types) and create a [TypeScript declaration file](https://www.typescriptlang.org/docs/handbook/2/type-declarations.html). +To ensure that the `env` object from `(await getCloudflareContext()).env` above has accurate TypeScript types, run the following Wrangler command to [generate types that match your Worker's configuration](https://developers.cloudflare.com/workers/languages/typescript/#generate-types-that-match-your-workers-configuration-experimental): -Install Workers Types: - -```sh -npm install --save-dev @cloudflare/workers-types ``` - -Add Workers Types to your `tsconfig.json` file, replacing the date below with your project's [compatibility date](https://developers.cloudflare.com/workers/configuration/compatibility-dates/): - -```diff title="tsconfig.json" - "types": [ -+ "@cloudflare/workers-types/2024-07-29" - ] +npx wrangler types --experimental-include-runtime ``` -Create an `env.d.ts` file in the root directory of your Next.js app, and explicitly declare the type of each binding: +This will generate a `d.ts` file and (by default) save it to `.wrangler/types/runtime.d.ts`. You will be prompted in the command's output to add that file to your `tsconfig.json`'s `compilerOptions.types` array. -```ts title="env.d.ts" -interface CloudflareEnv { - MY_KV_1: KVNamespace; - MY_KV_2: KVNamespace; - MY_R2: R2Bucket; - MY_DO: DurableObjectNamespace; -} +If you would like to commit the file to git, you can provide a custom path. Here, for instance, the `runtime.d.ts` file will be saved to the root of your project: + +```bash +npx wrangler types --experimental-include-runtime="./runtime.d.ts" ``` +To ensure that your types are always up-to-date, make sure to run `wrangler types --experimental-include-runtime` after any changes to your config file. + ## Other Cloudflare APIs (`cf`, `ctx`) You can access context about the incoming request from the [`cf` object](https://developers.cloudflare.com/workers/runtime-apis/request/#the-cf-property-requestinitcfproperties), as well as lifecycle methods from the [`ctx` object](https://developers.cloudflare.com/workers/runtime-apis/context) from the return value of [`getCloudflareContext()`](https://github.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src/api/get-cloudflare-context.ts): From f02cd910931ac7f662b567be723b365833c50d1a Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 08:36:00 +0100 Subject: [PATCH 13/20] bib/cloudflare --- pages/cloudflare/index.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx index d7d56e0..c81bfd4 100644 --- a/pages/cloudflare/index.mdx +++ b/pages/cloudflare/index.mdx @@ -18,7 +18,7 @@ You can also use [@cloudflare/next-on-pages](https://www.npmjs.com/package/@clou To create a new Next.js app, pre-configured to run on Cloudflare using @opennextjs/cloudflare, run: ``` - +npm create cloudflare@latest --no-auto-update --experimental --framework next ``` ##### Existing Next.js apps @@ -31,6 +31,10 @@ Next.js has [two "runtimes"](https://nextjs.org/docs/app/building-your-applicati This is an important difference from `@cloudflare/next-on-pages`, which only supports the "Edge" runtime. The Edge Runtime code in Next.js [intentionally constrains which APIs from Node.js can be used](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/plugins/middleware-plugin.ts#L820), and the "Edge" runtime does not support all Next.js features. +### Supported Next.js versions + +`@opennextjs/cloudflare` supports all minor and patch version of Next.js 13 and 14. + ### Supported Next.js features - [x] [App Router](https://nextjs.org/docs/app) & [Pages Router](https://nextjs.org/docs/pages) From 12c38b71efe46652313ac5387dcc455d51b60fa9 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 08:54:06 +0100 Subject: [PATCH 14/20] Add develop locally step --- pages/cloudflare/get-started.mdx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx index 5499198..bcb2733 100644 --- a/pages/cloudflare/get-started.mdx +++ b/pages/cloudflare/get-started.mdx @@ -79,7 +79,13 @@ id = "" As shown above, the name of the binding that you configure for the KV namespace must be set to `NEXT_CACHE_WORKERS_KV`. -##### 5. Deploy to Cloudflare Workers +##### 5. Develop locally + +You can continue to run `next dev` when developing locally. + +In step 3, we also added the `npm run preview:worker`, which allows you to quickly preview your app running locally in the Workers runtime, rather than in Node.js. This allows you to test changes in the same runtime as your app will run in when deployed to Cloudflare. + +##### 6. Deploy to Cloudflare Workers Either deploy via the command line: From 9197c495e4cb8ba8013409ea3f69a8bd1f5b0cb0 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 09:10:57 +0100 Subject: [PATCH 15/20] Size limit troubleshooting --- pages/cloudflare/troubleshooting.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pages/cloudflare/troubleshooting.mdx b/pages/cloudflare/troubleshooting.mdx index 3c939cf..a2ad091 100644 --- a/pages/cloudflare/troubleshooting.mdx +++ b/pages/cloudflare/troubleshooting.mdx @@ -3,6 +3,10 @@ import { Callout } from 'nextra/components'; ## Troubleshooting +### "Your Worker exceeded the size limit of 1 MiB" + +The Cloudflare Account you are deploying to is on the Workers Free plan, which [limits the size of each Worker to 1 MiB](https://developers.cloudflare.com/workers/platform/limits/#worker-size). When you subscribe to the Workers Paid plan, each Worker can be up to 10 MiB. + ### My app fails to build when I import a specific NPM package First, make sure that the `nodejs_compat` compatibility flag is enabled, and your compatibility date is set to on or after "2024-09-23", in your `wrangler.toml` file. [Refer to the Workers docs](https://developers.cloudflare.com/workers/runtime-apis/nodejs/) for more details on Node.js support in Cloudflare Workers. From 7a8e7ea37d933386aaa9a83f84fbd7ad77ebb225 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 09:15:32 +0100 Subject: [PATCH 16/20] Add note about Next.js versions --- pages/cloudflare/index.mdx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx index c81bfd4..4ac4fae 100644 --- a/pages/cloudflare/index.mdx +++ b/pages/cloudflare/index.mdx @@ -3,12 +3,12 @@ import { Callout } from 'nextra/components'; ## Cloudflare -The [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) adapter lets you deploy Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers) and [Cloudflare Pages](https://developers.cloudflare.com/pages), using the [Node.js "runtime" from Next.js](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes). +The [`@opennextjs/cloudflare`](https://www.npmjs.com/package/@opennextjs/cloudflare) adapter lets you deploy Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers) and [Cloudflare Pages](https://developers.cloudflare.com/pages), using the [Node.js "runtime" from Next.js](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes). -[@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) is pre 1.0, and still in active development. You should try it, [report bugs](https://github.com/opennextjs/opennextjs-cloudflare/issues), and [share feedback](https://github.com/opennextjs/opennextjs-cloudflare/discussions) to help make running Next.js apps on Cloudflare easier. We don't quite yet recommend using it for mission-critical production apps. +[`@opennextjs/cloudflare`](https://www.npmjs.com/package/@opennextjs/cloudflare) is pre 1.0, and still in active development. You should try it, [report bugs](https://github.com/opennextjs/opennextjs-cloudflare/issues), [share feedback](https://github.com/opennextjs/opennextjs-cloudflare/discussions), and contribute code to help make running Next.js apps on Cloudflare easier. We don't quite yet recommend using it for mission-critical production apps. -You can also use [@cloudflare/next-on-pages](https://www.npmjs.com/package/@cloudflare/next-on-pages) to deploy Next.js apps to Cloudflare Pages. You can review the differences in supported Next.js features between @opennextjs/cloudflare and @cloudflare/next-on-pages [here](LINK). +You can also use [`@cloudflare/next-on-pages`](https://www.npmjs.com/package/@cloudflare/next-on-pages) to deploy Next.js apps to Cloudflare Pages. You can review the differences in supported Next.js features between @opennextjs/cloudflare and @cloudflare/next-on-pages [here](LINK). ### Get Started @@ -33,7 +33,9 @@ This is an important difference from `@cloudflare/next-on-pages`, which only sup ### Supported Next.js versions -`@opennextjs/cloudflare` supports all minor and patch version of Next.js 13 and 14. +`@opennextjs/cloudflare` is pre 1.0, and still in active development. We intend to support all minor and patch version of Next.js 13 and 14, as well as Next.js 15 when it is released. (currently a release candidate) + +To help improve compatibility, we encourage you to [report bugs](https://github.com/opennextjs/opennextjs-cloudflare/issues) and contribute code! ### Supported Next.js features From 0e39722b5241318d5624c15a368dbfb581c63f30 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 09:18:26 +0100 Subject: [PATCH 17/20] Fixup --- pages/cloudflare/get-started.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx index bcb2733..7df8bd3 100644 --- a/pages/cloudflare/get-started.mdx +++ b/pages/cloudflare/get-started.mdx @@ -44,7 +44,7 @@ As shown above, you must enable the [`nodejs_compat` compatibility flag](https:/ Add the following to the scripts field of your `package.json` file: ```json -"build:worker": "cloudflare", TODO +"build:worker": "cloudflare", "dev:worker": "wrangler dev --port 8771", "preview:worker": "npm run build:worker && npm run dev:worker", "deploy:worker": "npm run build:worker && wrangler deploy" From 7587962148fe450d69f3bfa01bdfedb0347e84f9 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 09:35:29 +0100 Subject: [PATCH 18/20] Update supported features --- pages/cloudflare/index.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx index 4ac4fae..35da33b 100644 --- a/pages/cloudflare/index.mdx +++ b/pages/cloudflare/index.mdx @@ -44,14 +44,15 @@ To help improve compatibility, we encourage you to [report bugs](https://github. - [x] [Dynamic routes](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes) - [x] [Static Site Generation (SSG)](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) - [x] [Server-Side Rendering (SSR)](https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering) -- [x] [Incremental Static Regeneration (ISR)](https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration) +- [x] [Incremental Static Regeneration1 (ISR)](https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration) + +1 "Manual" revalidation is not supported (i.e. [`revalidateTag()`](https://nextjs.org/docs/app/api-reference/functions/revalidateTag) or [`revalidatePath()`](https://nextjs.org/docs/app/api-reference/functions/revalidatePath)) ### Not Yet Supported Next.js features - [ ] [Partial Prerendering (PPR)](https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering) - [ ] [Middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware) - [ ] [Image optimization](https://nextjs.org/docs/pages/building-your-application/optimizing/images) (you can integrate Cloudflare Images with Next.js by following [this guide](https://developers.cloudflare.com/images/transform-images/integrate-with-frameworks/)) -- [ ] [NextAuth.js](https://next-auth.js.org) - [ ] [Experimental streaming support](https://nextjs.org/blog/next-15-rc#executing-code-after-a-response-with-nextafter-experimental) ### How @opennextjs/cloudflare Works From a94d61213dbd93fab61ab3fb0437a3ff03e601b3 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 11:03:17 +0100 Subject: [PATCH 19/20] Update pages/cloudflare/index.mdx --- pages/cloudflare/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx index 35da33b..2a4d0f1 100644 --- a/pages/cloudflare/index.mdx +++ b/pages/cloudflare/index.mdx @@ -59,6 +59,6 @@ To help improve compatibility, we encourage you to [report bugs](https://github. The OpenNext Cloudflare adapter works by taking the Next.js build output and transforming it, so that it can run in Cloudflare Workers. -When you add [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) as a dependency to your Next.js app, and then run `pnpx cloudflare` (TODO: why pnpx?), the adapter first builds your app by running `next build`, and then transforms the build output to a format that you can run locally using [Wrangler](https://developers.cloudflare.com/workers/wrangler/), and deploy to Cloudflare. +When you add [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare) as a dependency to your Next.js app, and then run `npx cloudflare` the adapter first builds your app by running `next build`, and then transforms the build output to a format that you can run locally using [Wrangler](https://developers.cloudflare.com/workers/wrangler/), and deploy to Cloudflare. You can view the code for @opennextjs/cloudflare [here](https://github.com/opennextjs/opennextjs-cloudflare/blob/main/packages/cloudflare/src) to understand what it does under the hood. \ No newline at end of file From 6ab901913d5506fbe29e47335c7d99251b294b38 Mon Sep 17 00:00:00 2001 From: Brendan Irvine-Broque Date: Thu, 26 Sep 2024 11:07:49 +0100 Subject: [PATCH 20/20] Call out Cloudflare Workers <> Pages in Troubleshooting Some people may try to use `@opennextjs/cloudflare` to deploy to Cloudflare Pages, and we should explain compatibility and differences. --- pages/cloudflare/troubleshooting.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pages/cloudflare/troubleshooting.mdx b/pages/cloudflare/troubleshooting.mdx index a2ad091..1c06e1e 100644 --- a/pages/cloudflare/troubleshooting.mdx +++ b/pages/cloudflare/troubleshooting.mdx @@ -3,6 +3,14 @@ import { Callout } from 'nextra/components'; ## Troubleshooting +### Trying to deploy to Cloudflare Pages, instead of Cloudflare Workers? + +`@opennextjs/cloudflare` is specifically built for deploying Next.js apps to [Cloudflare Workers](https://developers.cloudflare.com/workers/) + +Cloudflare Workers now support the majority of functionality from Cloudflare Pages, and have features that are not yet supported by Cloudflare Pages. Refer to the [Compatibility Matrix](https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/) in the Cloudflare Workers docs. + +If you need to deploy to Cloudflare Pages, you can use `@cloudflare/next-on-pages`, and follow the [Cloudflare Pages guides for deploying Next.js apps](https://developers.cloudflare.com/pages/framework-guides/nextjs/). + ### "Your Worker exceeded the size limit of 1 MiB" The Cloudflare Account you are deploying to is on the Workers Free plan, which [limits the size of each Worker to 1 MiB](https://developers.cloudflare.com/workers/platform/limits/#worker-size). When you subscribe to the Workers Paid plan, each Worker can be up to 10 MiB.