diff --git a/pages/cloudflare/_meta.json b/pages/cloudflare/_meta.json
index e0d3688..0b730ce 100644
--- a/pages/cloudflare/_meta.json
+++ b/pages/cloudflare/_meta.json
@@ -7,9 +7,6 @@
"examples": "",
"community": "Community projects",
"troubleshooting": "",
- "migrate-from-0.4-to-0.5": "Migrate from 0.4",
- "migrate-from-0.3-to-0.4": "",
- "0.3": "Release 0.3",
- "migrate-from-0.2-to-0.3": "",
- "0.2": "Release 0.2"
+ "migrate-from-0.5-to-0.6": "Migrate from 0.5 to 0.6",
+ "former-releases": "Former releases"
}
diff --git a/pages/cloudflare/bindings.mdx b/pages/cloudflare/bindings.mdx
index 558fb15..df0a480 100644
--- a/pages/cloudflare/bindings.mdx
+++ b/pages/cloudflare/bindings.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
### Bindings
diff --git a/pages/cloudflare/caching.mdx b/pages/cloudflare/caching.mdx
index 8814995..b3bed4d 100644
--- a/pages/cloudflare/caching.mdx
+++ b/pages/cloudflare/caching.mdx
@@ -1,25 +1,28 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
+import { Tabs } from "nextra/components";
## Caching
`@opennextjs/cloudflare` supports [caching](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data).
-Next.js primes the cache at build time. The build time values are serverd by the [Workers Assets](https://developers.cloudflare.com/workers/static-assets/).
-
-
- 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` supports multiple caching mechanisms through a project's OpenNext configuration.
#### Incremental Static Regeneration (ISR)
-The ISR adapter for 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. Pricing information can be found in the Cloudflare [docs](https://developers.cloudflare.com/workers/platform/pricing/#workers-kv).
+There are two storage options to use for the incremental cache.
+
+- **Workers KV:** A [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. The build time values are serverd by the [Workers Assets](https://developers.cloudflare.com/workers/static-assets/). Pricing information can be found in the Cloudflare [docs](https://developers.cloudflare.com/workers/platform/pricing/#workers-kv).
+- **R2 Object Storage:** A [cost-effective](https://developers.cloudflare.com/r2/pricing/) S3-compatible object storage option for large amounts of unstructured data. Data is stored in a single region, meaning cache interactions may be slower - this can be mitigated with a regional cache.
+
+
+ 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.
+
+
+
##### 1. Create a KV namespace
```
@@ -28,68 +31,204 @@ npx wrangler@latest kv namespace create
##### 2. Add the KV namespace and Service Binding to your Worker
-The binding name used in your app's worker is `NEXT_CACHE_WORKERS_KV`. The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
+The binding name used in your app's worker is `NEXT_INC_CACHE_KV`.
+The `WORKER_SELF_REFERENCE` service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
```jsonc
// wrangler.jsonc
{
// ...
+ "name": "",
"kv_namespaces": [
{
- "binding": "NEXT_CACHE_WORKERS_KV",
+ "binding": "NEXT_INC_CACHE_KV",
"id": "",
},
],
"services": [
{
- "binding": "NEXT_CACHE_REVALIDATION_WORKER",
+ "binding": "WORKER_SELF_REFERENCE",
"service": "",
},
],
}
```
-#### 3. Configure the cache
+##### 3. Configure the cache
-In your project's OpenNext config, enable the KV cache and set up a queue.
+In your project's OpenNext config, enable the KV cache.
-The memory queue will send revalidation requests to a page when needed, and offers support for de-duplicating requests on a per-isolate basis. There might still be duplicate requests under high traffic or across regions.
+```ts
+// open-next.config.ts
+import { defineCloudflareConfig } from "@opennextjs/cloudflare";
+import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
+// ...
-
- The memory queue provided by `@opennextjs/cloudflare` is not fully suitable for production deployments, you
- can use it at your own risk!
-
+export default defineCloudflareConfig({
+ incrementalCache: kvIncrementalCache,
+ // ...
+});
+```
+
+
+
+
+
+##### 1. Create an R2 Bucket
+
+```
+npx wrangler@latest r2 bucket create
+```
+
+##### 2. Add the R2 Bucket and Service Binding to your Worker
+
+The binding name used in your app's worker is `NEXT_INC_CACHE_R2_BUCKET`. The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
+
+The prefix used by the R2 bucket can be configured with the `NEXT_INC_CACHE_R2_PREFIX` environment variable, and defaults to `incremental-cache`.
+
+```jsonc
+// wrangler.jsonc
+{
+ // ...
+ "name": "",
+ "r2_buckets": [
+ {
+ "binding": "NEXT_INC_CACHE_R2_BUCKET",
+ "bucket_name": "",
+ "preview_bucket_name": "",
+ },
+ ],
+ "services": [
+ {
+ "binding": "WORKER_SELF_REFERENCE",
+ "service": "",
+ },
+ ],
+}
+```
+
+##### 3. Configure the cache
+
+In your project's OpenNext config, enable the R2 cache.
+
+You can optionally setup a regional cache to use with the R2 incremental cache. This will enable faster retrieval of cache entries and reduce the amount of requests being sent to object storage.
+
+The regional cache has two modes:
+
+- `short-lived`: Responses are re-used for up to a minute.
+- `long-lived`: Fetch responses are re-used until revalidated, and ISR/SSG responses are re-used for up to 30 minutes.
+
+Additionally, lazy updating of the regional cache can be enabled with the `shouldLazilyUpdateOnCacheHit` option. When requesting data from the cache, it sends a background request to the R2 bucket to get the latest entry. This is enabled by default for the `long-lived` mode.
```ts
// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
-import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
-import memoryQueue from "@opennextjs/cloudflare/memory-queue";
+import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
+import { withRegionalCache } from "@opennextjs/cloudflare/overrides/incremental-cache/regional-cache";
+// ...
+// With regional cache enabled:
export default defineCloudflareConfig({
- incrementalCache: kvIncrementalCache,
- queue: memoryQueue,
+ incrementalCache: withRegionalCache(r2IncrementalCache, {
+ mode: "long-lived",
+ shouldLazilyUpdateOnCacheHit: true,
+ }),
+ // ...
+});
+
+// Without regional cache:
+export default defineCloudflareConfig({
+ incrementalCache: r2IncrementalCache,
+ // ...
+});
+```
+
+
+
+
+##### 4. Configure the queue
+
+In your project's OpenNext config, enable the cache and set up a queue.
+
+The Durable Object Queue will send revalidation requests to a page when needed, and offers support for de-duplicating requests.
+By default there will be a maximum of 10 instance of the Durables Object Queue and they can each process up to 5 requests in parallel, for up to 50 concurrent ISR revalidations.
+
+```ts
+// open-next.config.ts
+import { defineCloudflareConfig } from "@opennextjs/cloudflare";
+// ...
+import doQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";
+
+export default defineCloudflareConfig({
+ // ...
+ queue: doQueue,
});
```
+You will also need to add some binding to your `wrangler.jsonc` file.
+
+```jsonc
+"durable_objects": {
+ "bindings": [
+ {
+ "name": "NEXT_CACHE_DO_QUEUE",
+ "class_name": "DurableObjectQueueHandler"
+ }
+ ]
+ },
+ "migrations": [
+ {
+ "tag": "v1",
+ "new_sqlite_classes": ["DurableObjectQueueHandler"]
+ }
+ ],
+```
+
+You can customize the behaviors of the queue with environment variables:
+
+- The max number of revalidations that can be processed by an instance of durable object at the same time (`NEXT_CACHE_DO_QUEUE_MAX_REVALIDATION`)
+- The max time in milliseconds that a revalidation can take before being considered as failed (`NEXT_CACHE_DO_QUEUE_REVALIDATION_TIMEOUT_MS`)
+- The amount of time after which a revalidation will be attempted again if it failed. If it fails again it will exponentially back off until it reaches the max retry interval (`NEXT_CACHE_DO_QUEUE_RETRY_INTERVAL_MS`)
+- The maximum number of attempts that can be made to revalidate a path (`NEXT_CACHE_DO_QUEUE_MAX_NUM_REVALIDATIONS`)
+- Disable SQLite for this durable object. It should only be used if your incremental cache is not eventually consistent (`NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE`)
+
- The `direct` mode for the queue is intended for debugging purposes and is not recommended for use in
- production. We are actively working on a solution that will be suitable for production.
+ There is 2 additional modes that you can use for the queue `direct` and the memory queue
+
+- The memory queue will dedupe request but only on a per isolate basis. It is not fully suitable for production deployments, you
+ can use it at your own risk!
+
+- The `direct` mode for the queue is intended for debugging purposes and is not recommended for use in
+ production. It only works in preview mode (i.e. `wrangler dev`)
+
+ For apps using the Page Router, `res.revalidate` requires to provide a self reference service binding named `WORKER_SELF_REFERENCE`.
+
#### On-Demand Revalidation
-The tag revalidation mechanism uses a [Cloudflare D1](https://developers.cloudflare.com/d1/) database as its backing store for information about tags, paths, and revalidation times.
+The tag revalidation mechanism can use either a [Cloudflare D1](https://developers.cloudflare.com/d1/) database or [Durable Objects](https://developers.cloudflare.com/durable-objects/) with `SqliteStorage` as its backing store for information about tags, paths, and revalidation times.
To use on-demand revalidation, you should also follow the [ISR setup steps](#incremental-static-regeneration-isr).
If your app **only** uses the pages router, it does not need to have a tag cache and should skip this step.
+ You can also skip this step if your app doesn't to use `revalidateTag` nor `revalidatePath`.
+There are 3 different options to choose from for the tag cache: `d1NextTagCache`, `doShardedTagCache` and `d1TagCache`.
+Which one to choose should be based on two key factors:
+
+1. **Expected Load**: Consider the volume of traffic or data you anticipate.
+2. **Usage of** `revalidateTag` / `revalidatePath`: Evaluate how frequently these features will be utilized.
+
+If either of these factors is significant, opting for a sharded database is recommended. Additionally, incorporating a regional cache can further enhance performance.
+
+
+
##### 1. Create a D1 database and Service Binding
-The binding name used in your app's worker is `NEXT_CACHE_D1`. The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
+The binding name used in your app's worker is `NEXT_TAG_CACHE_D1`. The `WORKER_SELF_REFERENCE` service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
```jsonc
// wrangler.jsonc
@@ -97,36 +236,78 @@ The binding name used in your app's worker is `NEXT_CACHE_D1`. The service bindi
// ...
"d1_databases": [
{
- "binding": "NEXT_CACHE_D1",
+ "binding": "NEXT_TAG_CACHE_D1",
"database_id": "",
"database_name": "",
},
],
"services": [
{
- "binding": "NEXT_CACHE_REVALIDATION_WORKER",
+ "binding": "WORKER_SELF_REFERENCE",
"service": "",
},
],
}
```
-##### 2. Create tables for tag revalidations
+##### 2. Create table for tag revalidations
-The D1 tag cache requires two tables; one that keeps a record of the tag/path mappings, and another that tracks revalidation times.
+The D1 tag cache requires a `revalidations` table that tracks On-Demand revalidation times.
-For the tag mappings, the default table name is `tags`, and can be configured by setting the `NEXT_CACHE_D1_TAGS_TABLE` environment variable to a string.
+##### 3. Configure the cache
-For the revalidation times, the default table name is `revalidations` and can be configured by setting the `NEXT_CACHE_D1_REVALIDATIONS_TABLE` environment variable to a string.
+In your project's OpenNext config, enable the KV cache and set up a queue (see above). The queue will send a revalidation request to a page when needed, but it will not dedupe requests.
-Wrangler can be used to create a table with it's [execute](https://developers.cloudflare.com/d1/wrangler-commands/#d1-execute) option. Ensure that you create a table for both your local dev database and your remote database.
+```ts
+// open-next.config.ts
+import { defineCloudflareConfig } from "@opennextjs/cloudflare";
+import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
+import d1NextTagCache from "@opennextjs/cloudflare/d1-next-tag-cache";
+import memoryQueue from "@opennextjs/cloudflare/memory-queue";
-```sh
-wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS tags (tag TEXT NOT NULL, path TEXT NOT NULL, UNIQUE(tag, path) ON CONFLICT REPLACE)"
-wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE)"
+export default defineCloudflareConfig({
+ incrementalCache: kvIncrementalCache,
+ tagCache: d1NextTagCache,
+ queue: memoryQueue,
+});
```
-##### 3. Configure the cache
+
+
+
+##### 1. Create a Durable Object and Service Binding
+The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
+
+```jsonc
+// wrangler.jsonc
+{
+ // ...
+ "durable_objects": [
+ {
+ "name": "NEXT_CACHE_REVALIDATION_DURABLE_OBJECT",
+ "class_name": "DurableObjectQueueHandler",
+ },
+ {
+ "name": "NEXT_CACHE_DO_SHARDED",
+ "class_name": "DOShardedTagCache",
+ },
+ ],
+ "migrations": [
+ {
+ "tag": "v1",
+ "new_sqlite_classes": ["DurableObjectQueueHandler", "DOShardedTagCache"],
+ },
+ ],
+ "services": [
+ {
+ "binding": "WORKER_SELF_REFERENCE",
+ "service": "",
+ },
+ ],
+}
+```
+
+##### 2. Configure the cache
In your project's OpenNext config, enable the KV cache and set up a queue. The queue will send a revalidation request to a page when needed, but it will not dedupe requests.
@@ -134,9 +315,75 @@ In your project's OpenNext config, enable the KV cache and set up a queue. The q
// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
-import d1TagCache from "@opennextjs/cloudflare/d1-tag-cache";
+import doShardedTagCache from "@opennextjs/cloudflare/do-sharded-tag-cache";
import memoryQueue from "@opennextjs/cloudflare/memory-queue";
+export default defineCloudflareConfig({
+ incrementalCache: kvIncrementalCache,
+ tagCache: doShardedTagCache({ baseShardSize: 12, regionalCache: true }),
+ queue: memoryQueue,
+});
+```
+
+doShardedTagCache tahes the following options:
+
+- `baseShardSize` - The number of shards to use for the cache. The more shards you have, the more evenly the cache will be distributed across the shards. The default is 4. Soft (internal next tags used for `revalidatePath`) and hard tags (the one you define in your app) will be split in different shards
+- `regionalCache` - Whether to use regional cache for the cache. The default is false. This option is useful when you want to reduce the stress on the durable object
+- `regionalCacheTtlSec` - The TTL for the regional cache. The default is 5 seconds. Increasing this value will increase the time it takes for the cache to be invalidated across regions
+- `enableShardReplication`: Enable replicating the Shard. Shard replication will duplicate each shards into replicas to spread the load even more
+- `shardReplicationOptions.numberOfSoftReplicas`: Number of replicas for the soft tag shards
+- `shardReplicationOptions.numberOfHardReplicas`: Number of replicas for the hard tag shards
+- `maxWriteRetries`: The number of retries to perform when writing tags
+
+
+
+
+
+
+ The `d1TagCache` is not recommended for production use, as it does not scale well with the number of tags.
+
+
+##### 1. Create a D1 database and Service Binding
+
+The binding name used in your app's worker is `NEXT_CACHE_D1`. The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
+
+```jsonc
+// wrangler.jsonc
+{
+ // ...
+ "name": "",
+ "d1_databases": [
+ {
+ "binding": "NEXT_CACHE_D1",
+ "database_id": "",
+ "database_name": "",
+ },
+ ],
+ "services": [
+ {
+ "binding": "WORKER_SELF_REFERENCE",
+ "service": "",
+ },
+ ],
+}
+```
+
+The D1 database uses two tables, created when initialising the cache:
+
+- the "tags" table keeps a record of the tag/path mappings
+- the "revalidations" table tracks revalidation times
+
+##### 2. Configure the cache
+
+In your project's OpenNext config, enable the KV cache and set up a queue. The queue will send a revalidation request to a page when needed, but it will not dedupe requests.
+
+```ts
+// open-next.config.ts
+import { defineCloudflareConfig } from "@opennextjs/cloudflare";
+import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
+import d1TagCache from "@opennextjs/cloudflare/overrides/tag-cache/d1-tag-cache";
+import memoryQueue from "@opennextjs/cloudflare/overrides/queue/memory-queue";
+
export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
tagCache: d1TagCache,
@@ -144,14 +391,26 @@ export default defineCloudflareConfig({
});
```
-##### 4. Initialise the cache during deployments
+##### 3. Initialise the cache during deployments
-In order for the cache to be properly initialised with the build-time revalidation data, you need to setup a command that runs as part of your deploy step.
+In order for the cache to be properly initialised with the build-time revalidation data, you need to run a command as part of your deploy step. This should be run as part of each deployment to ensure that the cache is being populated with each build's data.
+
+To populate remote bindings and deploy your application at the same time, you can use the `deploy` command. Similarly, the `preview` command will populate your local bindings and start a Wrangler dev server.
+
+```sh
+# Populate remote and deploy.
+opennextjs-cloudflare deploy
+
+# Populate local and start dev server.
+opennextjs-cloudflare preview
+```
-OpenNext will generate an SQL file during the build that can be used to setup your D1 database.
+It is possible to only populate the cache without any other steps with the `populateCache` command.
```sh
-wrangler d1 execute NEXT_CACHE_D1 --file .open-next/cloudflare/cache-assets-manifest.sql
+# The target is passed as an option, either `local` or `remote`.
+opennextjs-cloudflare populateCache local
```
-This should be run as part of each deployment to ensure that the cache is being populated with each build's initial revalidation data.
+
+
diff --git a/pages/cloudflare/community.mdx b/pages/cloudflare/community.mdx
index 985b961..3ccd11f 100644
--- a/pages/cloudflare/community.mdx
+++ b/pages/cloudflare/community.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
## Projects from the community
diff --git a/pages/cloudflare/examples.mdx b/pages/cloudflare/examples.mdx
index bf5167b..e44bee0 100644
--- a/pages/cloudflare/examples.mdx
+++ b/pages/cloudflare/examples.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
## Examples
diff --git a/pages/cloudflare/0.2/_meta.json b/pages/cloudflare/former-releases/0.2/_meta.json
similarity index 100%
rename from pages/cloudflare/0.2/_meta.json
rename to pages/cloudflare/former-releases/0.2/_meta.json
diff --git a/pages/cloudflare/0.2/bindings.mdx b/pages/cloudflare/former-releases/0.2/bindings.mdx
similarity index 98%
rename from pages/cloudflare/0.2/bindings.mdx
rename to pages/cloudflare/former-releases/0.2/bindings.mdx
index f42790d..36d02b9 100644
--- a/pages/cloudflare/0.2/bindings.mdx
+++ b/pages/cloudflare/former-releases/0.2/bindings.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
### Bindings
diff --git a/pages/cloudflare/0.2/caching.mdx b/pages/cloudflare/former-releases/0.2/caching.mdx
similarity index 98%
rename from pages/cloudflare/0.2/caching.mdx
rename to pages/cloudflare/former-releases/0.2/caching.mdx
index e507e21..fab6edf 100644
--- a/pages/cloudflare/0.2/caching.mdx
+++ b/pages/cloudflare/former-releases/0.2/caching.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
## Caching
diff --git a/pages/cloudflare/0.2/examples.mdx b/pages/cloudflare/former-releases/0.2/examples.mdx
similarity index 96%
rename from pages/cloudflare/0.2/examples.mdx
rename to pages/cloudflare/former-releases/0.2/examples.mdx
index 4fd3469..6dd75b2 100644
--- a/pages/cloudflare/0.2/examples.mdx
+++ b/pages/cloudflare/former-releases/0.2/examples.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
## Examples
diff --git a/pages/cloudflare/0.2/get-started.mdx b/pages/cloudflare/former-releases/0.2/get-started.mdx
similarity index 99%
rename from pages/cloudflare/0.2/get-started.mdx
rename to pages/cloudflare/former-releases/0.2/get-started.mdx
index ea1482e..2e16213 100644
--- a/pages/cloudflare/0.2/get-started.mdx
+++ b/pages/cloudflare/former-releases/0.2/get-started.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
### Get Started
diff --git a/pages/cloudflare/0.2/index.mdx b/pages/cloudflare/former-releases/0.2/index.mdx
similarity index 99%
rename from pages/cloudflare/0.2/index.mdx
rename to pages/cloudflare/former-releases/0.2/index.mdx
index 2c39400..a3f53c2 100644
--- a/pages/cloudflare/0.2/index.mdx
+++ b/pages/cloudflare/former-releases/0.2/index.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
## Cloudflare
diff --git a/pages/cloudflare/0.3/_meta.json b/pages/cloudflare/former-releases/0.3/_meta.json
similarity index 100%
rename from pages/cloudflare/0.3/_meta.json
rename to pages/cloudflare/former-releases/0.3/_meta.json
diff --git a/pages/cloudflare/0.3/bindings.mdx b/pages/cloudflare/former-releases/0.3/bindings.mdx
similarity index 98%
rename from pages/cloudflare/0.3/bindings.mdx
rename to pages/cloudflare/former-releases/0.3/bindings.mdx
index d0af91d..1b3164d 100644
--- a/pages/cloudflare/0.3/bindings.mdx
+++ b/pages/cloudflare/former-releases/0.3/bindings.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
### Bindings
diff --git a/pages/cloudflare/0.3/caching.mdx b/pages/cloudflare/former-releases/0.3/caching.mdx
similarity index 98%
rename from pages/cloudflare/0.3/caching.mdx
rename to pages/cloudflare/former-releases/0.3/caching.mdx
index 47e9168..1314873 100644
--- a/pages/cloudflare/0.3/caching.mdx
+++ b/pages/cloudflare/former-releases/0.3/caching.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
## Caching
diff --git a/pages/cloudflare/0.3/examples.mdx b/pages/cloudflare/former-releases/0.3/examples.mdx
similarity index 97%
rename from pages/cloudflare/0.3/examples.mdx
rename to pages/cloudflare/former-releases/0.3/examples.mdx
index d75a1f6..e44bee0 100644
--- a/pages/cloudflare/0.3/examples.mdx
+++ b/pages/cloudflare/former-releases/0.3/examples.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
## Examples
diff --git a/pages/cloudflare/0.3/get-started.mdx b/pages/cloudflare/former-releases/0.3/get-started.mdx
similarity index 99%
rename from pages/cloudflare/0.3/get-started.mdx
rename to pages/cloudflare/former-releases/0.3/get-started.mdx
index de6091d..1345e34 100644
--- a/pages/cloudflare/0.3/get-started.mdx
+++ b/pages/cloudflare/former-releases/0.3/get-started.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
### Get Started
diff --git a/pages/cloudflare/0.3/index.mdx b/pages/cloudflare/former-releases/0.3/index.mdx
similarity index 98%
rename from pages/cloudflare/0.3/index.mdx
rename to pages/cloudflare/former-releases/0.3/index.mdx
index 79748c6..b44423e 100644
--- a/pages/cloudflare/0.3/index.mdx
+++ b/pages/cloudflare/former-releases/0.3/index.mdx
@@ -1,6 +1,5 @@
-import { SITE } from "../../../config";
import { Callout } from "nextra/components";
-import WindowsSupport from "../../../shared/WindowsSupport.mdx";
+import WindowsSupport from "../../../../shared/WindowsSupport.mdx";
## Cloudflare
diff --git a/pages/cloudflare/former-releases/0.5/_meta.json b/pages/cloudflare/former-releases/0.5/_meta.json
new file mode 100644
index 0000000..53a20a0
--- /dev/null
+++ b/pages/cloudflare/former-releases/0.5/_meta.json
@@ -0,0 +1,7 @@
+{
+ "index": "Overview",
+ "get-started": "",
+ "bindings": "",
+ "caching": "",
+ "examples": ""
+}
diff --git a/pages/cloudflare/former-releases/0.5/bindings.mdx b/pages/cloudflare/former-releases/0.5/bindings.mdx
new file mode 100644
index 0000000..df0a480
--- /dev/null
+++ b/pages/cloudflare/former-releases/0.5/bindings.mdx
@@ -0,0 +1,74 @@
+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.
+
+#### 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 configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/) in the root directory of your Next.js app, as described in [Get Started](/cloudflare/get-started#3-create-a-wranglerjson-file).
+
+#### 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 `getCloudflareContext`:
+
+```js
+import { getCloudflareContext } from "@opennextjs/cloudflare";
+
+export async function GET(request) {
+ let responseText = "Hello World";
+
+ const myKv = getCloudflareContext().env.MY_KV_NAMESPACE;
+ await myKv.put("foo", "bar");
+ const foo = await myKv.get("foo");
+
+ return new Response(foo);
+}
+```
+
+
+ `getCloudflareContext` can only be used in SSG routes in "async mode" (making it return a promise), to run the function in such a way simply provide an options argument with `async` set to `true`:
+ ```js
+ const context = await getCloudflareContext({ async: true });
+ ```
+
+ **WARNING**: During SSG caution is advised since secrets (stored in `.dev.vars` files) and local development
+ values from bindings (like values saved in a local KV) will be used for the pages static generation.
+
+
+
+#### How to add bindings to your Worker
+
+Add bindings to your Worker by adding them to your [wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/).
+
+## TypeScript type declarations for bindings
+
+To ensure that the `env` object from `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):
+
+```
+npx wrangler types --experimental-include-runtime
+```
+
+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.
+
+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):
+
+```js
+import { getCloudflareContext } from "@opennextjs/cloudflare";
+
+export async function GET(request) {
+ const { env, cf, ctx } = getCloudflareContext();
+
+ // ...
+}
+```
diff --git a/pages/cloudflare/former-releases/0.5/caching.mdx b/pages/cloudflare/former-releases/0.5/caching.mdx
new file mode 100644
index 0000000..c5eed52
--- /dev/null
+++ b/pages/cloudflare/former-releases/0.5/caching.mdx
@@ -0,0 +1,156 @@
+import { Callout } from "nextra/components";
+
+## Caching
+
+`@opennextjs/cloudflare` supports [caching](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data).
+
+Next.js primes the cache at build time. The build time values are serverd by the [Workers Assets](https://developers.cloudflare.com/workers/static-assets/).
+
+
+ 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` supports multiple caching mechanisms through a project's OpenNext configuration.
+
+#### Incremental Static Regeneration (ISR)
+
+The ISR adapter for 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. Pricing information can be found in the Cloudflare [docs](https://developers.cloudflare.com/workers/platform/pricing/#workers-kv).
+
+##### 1. Create a KV namespace
+
+```
+npx wrangler@latest kv namespace create
+```
+
+##### 2. Add the KV namespace and Service Binding to your Worker
+
+The binding name used in your app's worker is `NEXT_CACHE_WORKERS_KV`. The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
+
+```jsonc
+// wrangler.jsonc
+{
+ // ...
+ "kv_namespaces": [
+ {
+ "binding": "NEXT_CACHE_WORKERS_KV",
+ "id": "",
+ },
+ ],
+ "services": [
+ {
+ "binding": "NEXT_CACHE_REVALIDATION_WORKER",
+ "service": "",
+ },
+ ],
+}
+```
+
+#### 3. Configure the cache
+
+In your project's OpenNext config, enable the KV cache and set up a queue.
+
+The memory queue will send revalidation requests to a page when needed, and offers support for de-duplicating requests on a per-isolate basis. There might still be duplicate requests under high traffic or across regions.
+
+
+ The memory queue provided by `@opennextjs/cloudflare` is not fully suitable for production deployments, you
+ can use it at your own risk!
+
+
+```ts
+// open-next.config.ts
+import { defineCloudflareConfig } from "@opennextjs/cloudflare";
+import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
+import memoryQueue from "@opennextjs/cloudflare/memory-queue";
+
+export default defineCloudflareConfig({
+ incrementalCache: kvIncrementalCache,
+ queue: memoryQueue,
+});
+```
+
+
+ The `direct` mode for the queue is intended for debugging purposes and is not recommended for use in
+ production. We are actively working on a solution that will be suitable for production.
+
+
+#### On-Demand Revalidation
+
+The tag revalidation mechanism uses a [Cloudflare D1](https://developers.cloudflare.com/d1/) database as its backing store for information about tags, paths, and revalidation times.
+
+To use on-demand revalidation, you should also follow the [ISR setup steps](#incremental-static-regeneration-isr).
+
+
+ If your app **only** uses the pages router, it does not need to have a tag cache and should skip this step.
+
+
+##### 1. Create a D1 database and Service Binding
+
+The binding name used in your app's worker is `NEXT_CACHE_D1`. The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file.
+
+```jsonc
+// wrangler.jsonc
+{
+ // ...
+ "d1_databases": [
+ {
+ "binding": "NEXT_CACHE_D1",
+ "database_id": "",
+ "database_name": "",
+ },
+ ],
+ "services": [
+ {
+ "binding": "NEXT_CACHE_REVALIDATION_WORKER",
+ "service": "",
+ },
+ ],
+}
+```
+
+##### 2. Create tables for tag revalidations
+
+The D1 tag cache requires two tables; one that keeps a record of the tag/path mappings, and another that tracks revalidation times.
+
+For the tag mappings, the default table name is `tags`, and can be configured by setting the `NEXT_CACHE_D1_TAGS_TABLE` environment variable to a string.
+
+For the revalidation times, the default table name is `revalidations` and can be configured by setting the `NEXT_CACHE_D1_REVALIDATIONS_TABLE` environment variable to a string.
+
+Wrangler can be used to create a table with it's [execute](https://developers.cloudflare.com/d1/wrangler-commands/#d1-execute) option. Ensure that you create a table for both your local dev database and your remote database.
+
+```sh
+wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS tags (tag TEXT NOT NULL, path TEXT NOT NULL, UNIQUE(tag, path) ON CONFLICT REPLACE)"
+wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE)"
+```
+
+##### 3. Configure the cache
+
+In your project's OpenNext config, enable the KV cache and set up a queue. The queue will send a revalidation request to a page when needed, but it will not dedupe requests.
+
+```ts
+// open-next.config.ts
+import { defineCloudflareConfig } from "@opennextjs/cloudflare";
+import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
+import d1TagCache from "@opennextjs/cloudflare/d1-tag-cache";
+import memoryQueue from "@opennextjs/cloudflare/memory-queue";
+
+export default defineCloudflareConfig({
+ incrementalCache: kvIncrementalCache,
+ tagCache: d1TagCache,
+ queue: memoryQueue,
+});
+```
+
+##### 4. Initialise the cache during deployments
+
+In order for the cache to be properly initialised with the build-time revalidation data, you need to setup a command that runs as part of your deploy step.
+
+OpenNext will generate an SQL file during the build that can be used to setup your D1 database.
+
+```sh
+wrangler d1 execute NEXT_CACHE_D1 --file .open-next/cloudflare/cache-assets-manifest.sql
+```
+
+This should be run as part of each deployment to ensure that the cache is being populated with each build's initial revalidation data.
diff --git a/pages/cloudflare/former-releases/0.5/examples.mdx b/pages/cloudflare/former-releases/0.5/examples.mdx
new file mode 100644
index 0000000..e44bee0
--- /dev/null
+++ b/pages/cloudflare/former-releases/0.5/examples.mdx
@@ -0,0 +1,24 @@
+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 -- my-next-app --framework=next --experimental
+```
+
+### Basic starter projects
+
+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
+- [_`middleware`_](https://github.com/opennextjs/opennextjs-cloudflare/tree/main/examples/middleware) — a minimal Next.js project using middleware
+- [_`vercel-blog-starter`_](https://github.com/opennextjs/opennextjs-cloudflare/tree/main/examples/vercel-blog-starter) — a blog project using SSG
+
+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](https://vercel-commerce-on-workers.web-experiments.workers.dev/).
diff --git a/pages/cloudflare/former-releases/0.5/get-started.mdx b/pages/cloudflare/former-releases/0.5/get-started.mdx
new file mode 100644
index 0000000..f1d70dd
--- /dev/null
+++ b/pages/cloudflare/former-releases/0.5/get-started.mdx
@@ -0,0 +1,190 @@
+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:
+
+```sh
+npm create cloudflare@latest -- my-next-app --framework=next --experimental
+```
+
+#### Existing Next.js apps
+
+##### 1. Install @opennextjs/cloudflare
+
+First, install [@opennextjs/cloudflare](https://www.npmjs.com/package/@opennextjs/cloudflare):
+
+```sh
+npm install --save-dev @opennextjs/cloudflare@latest
+```
+
+##### 2. Install Wrangler
+
+Install the [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/) as a devDependency:
+
+```sh
+npm install --save-dev wrangler@latest
+```
+
+
+ You must use Wrangler version `3.99.0` or later to deploy Next.js apps using `@opennextjs/cloudflare`.
+
+
+##### 3. Create a wrangler configuration file
+
+
+ This step is optional since `@opennextjs/cloudflare` creates this file for you during the build process (if
+ not already present).
+
+
+A [wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/) is needed for your
+application to be previewed and deployed, it is also where you configure your Worker and define what resources it can access via [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings).
+
+You can create one yourself in the root directory of your Next.js app with the name `wrangler.jsonc` and the following content:
+
+```jsonc
+{
+ "$schema": "node_modules/wrangler/config-schema.json",
+ "main": ".open-next/worker.js",
+ "name": "my-app",
+ "compatibility_date": "2024-12-30",
+ "compatibility_flags": ["nodejs_compat"],
+ "assets": {
+ "directory": ".open-next/assets",
+ "binding": "ASSETS",
+ },
+ "kv_namespaces": [
+ // Create a KV binding with the binding name "NEXT_CACHE_WORKERS_KV"
+ // to enable the KV based caching:
+ // {
+ // "binding": "NEXT_CACHE_WORKERS_KV",
+ // "id": ""
+ // }
+ ],
+}
+```
+
+
+ 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 - The `main` and `assets` values
+ should also not be changed unless you modify the build output result in some way - You can add a binding
+ named `NEXT_CACHE_WORKERS_KV` to make use of Next.js' caching as described in the [Caching
+ docs](/cloudflare/caching)
+
+
+##### 4. Add an `open-next.config.ts` file
+
+
+ This step is optional since `@opennextjs/cloudflare` creates this file for you during the build process (if
+ not already present).
+
+
+Add a [`open-next.config.ts`](https://opennext.js.org/aws/config) file to the root directory of your Next.js app:
+
+```ts
+import { defineCloudflareConfig } from "@opennextjs/cloudflare";
+import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
+
+export default defineCloudflareConfig({
+ incrementalCache: kvIncrementalCache,
+});
+```
+
+
+ To use the `OpenNextConfig` type as illustrated above (which is not necessary), you need to install the
+ `@opennextjs/aws` NPM package as a dev dependency.
+
+
+##### 5. Add a `.dev.vars` file
+
+Then, add a [`.dev.vars`](https://developers.cloudflare.com/workers/testing/local-development/#local-only-environment-variables) file to the root directory of your Next.js app:
+
+```text
+NEXTJS_ENV=development
+```
+
+The `NEXTJS_ENV` variable defines the environment to use when loading Next.js `.env` files. It defaults to "production" when not defined.
+
+##### 6. Update the `package.json` file
+
+Add the following to the scripts field of your `package.json` file:
+
+```json
+"preview": "opennextjs-cloudflare && wrangler dev",
+"deploy": "opennextjs-cloudflare && wrangler deploy",
+"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts",
+```
+
+- `npm run preview`: Builds your app and serves it locally, 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
+- `cf-typegen`: Generates a `cloudflare-env.d.ts` file at the root of your project containing [the types for the `env`](https://developers.cloudflare.com/workers/wrangler/commands/#types).
+
+##### 7. Add caching with Workers KV
+
+See the [Caching docs](/cloudflare/caching) for information on enabling Next.js caching in your OpenNext project.
+
+##### 8. Remove any `export const runtime = "edge";` if present
+
+Before deploying your app, remove the `export const runtime = "edge";` line from any of your source files.
+
+The edge runtime is not supported yet with `@opennextjs/cloudflare`.
+
+##### 9. Add `.open-next` to `.gitignore`
+
+You should add `.open-next` to your `.gitignore` file to prevent the build output from being committed to your repository.
+
+##### 10. Remove `@cloudflare/next-on-pages` (if necessary)
+
+If your Next.js app currently uses `@cloudflare/next-on-pages`, you'll want to remove it, and make a few changes.
+
+Uninstalling the [`@cloudflare/next-on-pages`](https://www.npmjs.com/package/@cloudflare/next-on-pages) package as well as the [`eslint-plugin-next-on-pages`](https://www.npmjs.com/package/eslint-plugin-next-on-pages) package if present.
+
+Remove any reference of these packages from your source and configuration files.
+This includes:
+
+- `setupDevPlatform()` calls in your Next.js config file
+- `getRequestContext` imports from `@cloudflare/next-on-pages` from your source files
+ (those can be replaced with `getCloudflareContext` calls from `@opennextjs/cloudflare`)
+- next-on-pages eslint rules set in your Eslint config file
+
+##### 11. Develop locally
+
+You can continue to run `next dev` when developing locally.
+
+Modify your Next.js configuration file to import and call the `initOpenNextCloudflareForDev` utility
+from the `@opennextjs/cloudflare` package. This makes sure that the Next.js dev server can optimally integrate with the open-next cloudflare adapter and it is necessary for using bindings during local development.
+
+This is an example of a Next.js configuration file calling the utility:
+
+```ts
+// next.config.ts
+import type { NextConfig } from "next";
+
+const nextConfig: NextConfig = {
+ /* config options here */
+};
+
+export default nextConfig;
+
+import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
+initOpenNextCloudflareForDev();
+```
+
+After having added the `initOpenNextCloudflareForDev()` call in your Next.js configuration file, you will be able, during local development, to access in any of your server code, local versions of Cloudflare bindings as indicated in the [bindings documentation](./bindings).
+
+In step 3, we also added the `npm run preview`, 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.
+
+##### 12. Deploy to Cloudflare Workers
+
+Either deploy via the command line:
+
+```sh
+npm run deploy
+```
+
+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.
diff --git a/pages/cloudflare/former-releases/0.5/index.mdx b/pages/cloudflare/former-releases/0.5/index.mdx
new file mode 100644
index 0000000..cdb70bb
--- /dev/null
+++ b/pages/cloudflare/former-releases/0.5/index.mdx
@@ -0,0 +1,73 @@
+import { Callout } from "nextra/components";
+import WindowsSupport from "../../../../shared/WindowsSupport.mdx";
+
+## 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) 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), [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 below and by reviewing [the docs for `@cloudflare/next-on-pages`](https://developers.cloudflare.com/pages/framework-guides/nextjs/ssr/supported-features/), and understand the differences between Workers and Pages [here](https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/).
+
+
+
+### Get Started
+
+##### New apps
+
+To create a new Next.js app, pre-configured to run on Cloudflare using `@opennextjs/cloudflare`, run:
+
+```
+npm create cloudflare@latest -- my-next-app --framework=next --experimental
+```
+
+##### 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 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 should use the Node.js runtime, which is more fully featured, and allows you to use the [Node.js APIs](https://developers.cloudflare.com/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 versions
+
+`@opennextjs/cloudflare` is pre 1.0, and still in active development. We intend to support all minor and patch versions of Next.js 15 and the latest minor of Next.js 14.
+
+To help improve compatibility, we encourage you to [report bugs](https://github.com/opennextjs/opennextjs-cloudflare/issues) and contribute code!
+
+### Supported Next.js features
+
+Some Next.js features are not yet supported are not fully tested.
+We will update the list as we progress towards releasing 1.0.
+
+- [x] [App Router](https://nextjs.org/docs/app)
+- [x] [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)
+- [x] [Dynamic routes](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes)
+- [x] [Static Site Generation (SSG)](https://nextjs.org/docs/app/building-your-application/rendering/server-components#static-rendering-default)
+- [x] [Server-Side Rendering (SSR)](https://nextjs.org/docs/app/building-your-application/rendering/server-components)
+- [x] [Middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware)
+- [x] [Image optimization](https://nextjs.org/docs/app/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/))
+- [x] [Partial Prerendering (PPR)](https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering)
+- [x] [Pages Router](https://nextjs.org/docs/pages)
+- [x] [Incremental Static Regeneration (ISR)](https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration) 1
+- [x] [Support for after](https://nextjs.org/blog/next-15-rc#executing-code-after-a-response-with-nextafter-experimental)
+- [ ] [Composable Caching](https://nextjs.org/blog/composable-caching) (`'use cache'`) is a Next.js 15 feature and not supported yet.
+
+1 Only the `direct` mode is supported at the moment, and is not suitable for production.
+
+We welcome both contributions and feedback!
+
+### Windows 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 `npx opennextjs-cloudflare` the adapter first builds your app by running the `build` script in your `package.json`, 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.
diff --git a/pages/cloudflare/former-releases/_meta.json b/pages/cloudflare/former-releases/_meta.json
new file mode 100644
index 0000000..fcfac6d
--- /dev/null
+++ b/pages/cloudflare/former-releases/_meta.json
@@ -0,0 +1,8 @@
+{
+ "0.5": "Release 0.5",
+ "migrate-from-0.4-to-0.5": "",
+ "migrate-from-0.3-to-0.4": "",
+ "0.3": "Release 0.3",
+ "migrate-from-0.2-to-0.3": "",
+ "0.2": "Release 0.2"
+}
diff --git a/pages/cloudflare/migrate-from-0.2-to-0.3.mdx b/pages/cloudflare/former-releases/migrate-from-0.2-to-0.3.mdx
similarity index 98%
rename from pages/cloudflare/migrate-from-0.2-to-0.3.mdx
rename to pages/cloudflare/former-releases/migrate-from-0.2-to-0.3.mdx
index e43347a..e213c6f 100644
--- a/pages/cloudflare/migrate-from-0.2-to-0.3.mdx
+++ b/pages/cloudflare/former-releases/migrate-from-0.2-to-0.3.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
### Migrate from 0.2 to 0.3
diff --git a/pages/cloudflare/migrate-from-0.3-to-0.4.mdx b/pages/cloudflare/former-releases/migrate-from-0.3-to-0.4.mdx
similarity index 97%
rename from pages/cloudflare/migrate-from-0.3-to-0.4.mdx
rename to pages/cloudflare/former-releases/migrate-from-0.3-to-0.4.mdx
index ca8da55..70fb364 100644
--- a/pages/cloudflare/migrate-from-0.3-to-0.4.mdx
+++ b/pages/cloudflare/former-releases/migrate-from-0.3-to-0.4.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
### Migrate from 0.3 to 0.4
diff --git a/pages/cloudflare/migrate-from-0.4-to-0.5.mdx b/pages/cloudflare/former-releases/migrate-from-0.4-to-0.5.mdx
similarity index 100%
rename from pages/cloudflare/migrate-from-0.4-to-0.5.mdx
rename to pages/cloudflare/former-releases/migrate-from-0.4-to-0.5.mdx
diff --git a/pages/cloudflare/get-started.mdx b/pages/cloudflare/get-started.mdx
index 8a7c29e..5b1e9b0 100644
--- a/pages/cloudflare/get-started.mdx
+++ b/pages/cloudflare/get-started.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
### Get Started
@@ -56,11 +55,18 @@ You can create one yourself in the root directory of your Next.js app with the n
"directory": ".open-next/assets",
"binding": "ASSETS",
},
+ "services": [
+ {
+ "binding": "WORKER_SELF_REFERENCE",
+ // The service should match the "name" of your worker
+ "service": "my-app",
+ },
+ ],
"kv_namespaces": [
- // Create a KV binding with the binding name "NEXT_CACHE_WORKERS_KV"
+ // Create a KV binding with the binding name "NEXT_INC_CACHE_KV"
// to enable the KV based caching:
// {
- // "binding": "NEXT_CACHE_WORKERS_KV",
+ // "binding": "NEXT_INC_CACHE_KV",
// "id": ""
// }
],
@@ -73,7 +79,7 @@ You can create one yourself in the root directory of your Next.js app with the n
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 - The `main` and `assets` values
should also not be changed unless you modify the build output result in some way - You can add a binding
- named `NEXT_CACHE_WORKERS_KV` to make use of Next.js' caching as described in the [Caching
+ named `NEXT_INC_CACHE_KV` to make use of Next.js' caching as described in the [Caching
docs](/cloudflare/caching)
@@ -88,7 +94,7 @@ Add a [`open-next.config.ts`](https://opennext.js.org/aws/config) file to the ro
```ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
-import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
+import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
@@ -115,8 +121,8 @@ The `NEXTJS_ENV` variable defines the environment to use when loading Next.js `.
Add the following to the scripts field of your `package.json` file:
```json
-"preview": "opennextjs-cloudflare && wrangler dev",
-"deploy": "opennextjs-cloudflare && wrangler deploy",
+"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",
```
diff --git a/pages/cloudflare/howtos/_meta.json b/pages/cloudflare/howtos/_meta.json
index 2dae0f9..e4803ff 100644
--- a/pages/cloudflare/howtos/_meta.json
+++ b/pages/cloudflare/howtos/_meta.json
@@ -2,5 +2,6 @@
"NextAuth": "NextAuth",
"stripeAPI": "Stripe API",
"dev": "Development workflow",
- "env-vars": "Enviroment Variables"
+ "env-vars": "Enviroment Variables",
+ "image": "Image Optimization"
}
diff --git a/pages/cloudflare/howtos/dev.mdx b/pages/cloudflare/howtos/dev.mdx
index a8a901f..0d5b39f 100644
--- a/pages/cloudflare/howtos/dev.mdx
+++ b/pages/cloudflare/howtos/dev.mdx
@@ -38,7 +38,7 @@ initOpenNextCloudflareForDev();
### `wrangler dev` and `wrangler deploy`
-After you've finished iterating on your Next.js application with `next dev`, you can convert it to a Cloudflare Worker by running the `opennextjs-cloudflare` command. This will generate the Worker code in the `.open-next` directory.
+After you've finished iterating on your Next.js application with `next dev`, you can convert it to a Cloudflare Worker by running the `opennextjs-cloudflare build` command. This will generate the Worker code in the `.open-next` directory.
You can then preview the app locally in the Cloudflare Workers runtime or deploy it to the Cloudflare network.
diff --git a/pages/cloudflare/howtos/image.mdx b/pages/cloudflare/howtos/image.mdx
new file mode 100644
index 0000000..fd4e2ae
--- /dev/null
+++ b/pages/cloudflare/howtos/image.mdx
@@ -0,0 +1,64 @@
+import { Callout } from "nextra/components";
+
+## Image Optimization
+
+Next.js has a builtin [`` component](https://nextjs.org/docs/pages/building-your-application/optimizing/images) to automatically optimize your images for faster page loads.
+
+In this post, we will look at how to integrate the Next.js image optimization with [Cloudflare Images](https://developers.cloudflare.com/images)
+
+### Enable Cloudflare Images
+
+You first need to [enable Cloudflare Images](https://developers.cloudflare.com/images/get-started/#enable-transformations-on-your-zone) for your zone.
+
+It is strongly advised to restrict the image origins that can be transformed to where your images are hosted, i.e. a [R2 bucket](https://developers.cloudflare.com/r2/buckets/).
+
+### Use a custom loader
+
+You then need to configure your Next application to use a custom loader for Cloudflare Images.
+
+Create an `image-loader.ts` at the root of your application:
+
+```ts
+// image-loader.ts
+import type { ImageLoaderProps } from "next/image";
+
+const normalizeSrc = (src: string) => {
+ return src.startsWith("/") ? src.slice(1) : src;
+};
+
+export default function cloudflareLoader({ src, width, quality }: ImageLoaderProps) {
+ if (process.env.NODE_ENV === "development") {
+ // Serve the original image when using `next dev`
+ return src;
+ }
+ const params = [`width=${width}`];
+ if (quality) {
+ params.push(`quality=${quality}`);
+ }
+ const paramsString = params.join(",");
+ return `/cdn-cgi/image/${paramsString}/${normalizeSrc(src)}`;
+}
+```
+
+You will then need to update your app configuration to use this loader:
+
+```ts
+// next.config.ts
+import type { NextConfig } from "next";
+
+const nextConfig: NextConfig = {
+ // ...
+ images: {
+ loader: "custom",
+ loaderFile: "./image-loader.ts",
+ },
+};
+
+export default nextConfig;
+```
+
+
+ Images using the cloudflare loader are served directly without going through the middleware.
+
+
+See more details in the [Cloudfare Images documentation](https://developers.cloudflare.com/images/transform-images/integrate-with-frameworks/).
diff --git a/pages/cloudflare/index.mdx b/pages/cloudflare/index.mdx
index 8069067..5cc52a6 100644
--- a/pages/cloudflare/index.mdx
+++ b/pages/cloudflare/index.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
import WindowsSupport from "../../shared/WindowsSupport.mdx";
@@ -6,13 +5,6 @@ import WindowsSupport from "../../shared/WindowsSupport.mdx";
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) 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), [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 below and by reviewing [the docs for `@cloudflare/next-on-pages`](https://developers.cloudflare.com/pages/framework-guides/nextjs/ssr/supported-features/), and understand the differences between Workers and Pages [here](https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/).
-
-
-
### Get Started
##### New apps
@@ -50,7 +42,7 @@ We will update the list as we progress towards releasing 1.0.
- [x] [Static Site Generation (SSG)](https://nextjs.org/docs/app/building-your-application/rendering/server-components#static-rendering-default)
- [x] [Server-Side Rendering (SSR)](https://nextjs.org/docs/app/building-your-application/rendering/server-components)
- [x] [Middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware)
-- [x] [Image optimization](https://nextjs.org/docs/app/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/))
+- [x] [Image optimization](https://nextjs.org/docs/app/building-your-application/optimizing/images) (See [this guide](/cloudflare/howtos/image) to configure [Cloudfare Images](https://developers.cloudflare.com/images/))
- [x] [Partial Prerendering (PPR)](https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering)
- [x] [Pages Router](https://nextjs.org/docs/pages)
- [x] [Incremental Static Regeneration (ISR)](https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration) 1
diff --git a/pages/cloudflare/migrate-from-0.5-to-0.6.mdx b/pages/cloudflare/migrate-from-0.5-to-0.6.mdx
new file mode 100644
index 0000000..de1ab56
--- /dev/null
+++ b/pages/cloudflare/migrate-from-0.5-to-0.6.mdx
@@ -0,0 +1,40 @@
+import { Callout } from "nextra/components";
+
+### Migrate from 0.5 to 0.6
+
+`@opennextjs/cloudflare@0.6.0` introduces more options for caching.
+
+The codebase has been refactored with some breaking changes, read-on to update your apps:
+
+##### Overrides location
+
+The cloudflare overrides now live in `@opennextjs/cloudflare/overrides`:
+
+- Incremental cache overrides: `@opennextjs/cloudflare/overrides/incremental-cache/...`
+- Tag cache overrides: `@opennextjs/cloudflare/overrides/tag-cache/...`
+- Queue overrides: `@opennextjs/cloudflare/overrides/queue/...`
+
+For example the KV incremental cache override can be now imported as `@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache`.
+
+##### Environment variables and bindings
+
+We have updated the name for consistency:
+
+- `NEXT_CACHE_WORKERS_KV` -> `NEXT_INC_CACHE_KV`
+- `NEXT_CACHE_R2_...` -> `NEXT_INC_CACHE_R2_...`
+- `NEXT_CACHE_D1` -> `NEXT_TAG_CACHE_D1`
+- `NEXT_CACHE_DO_...` -> `NEXT_TAG_CACHE_DO_...`
+- `NEXT_CACHE_DO_REVALIDATION` -> `NEXT_CACHE_DO_QUEUE`
+- `NEXT_CACHE_REVALIDATION_WORKER` -> `WORKER_SELF_REFERENCE`
+
+`NEXT_CACHE_D1_TAGS_TABLE` and `NEXT_CACHE_D1_REVALIDATIONS_TABLE` have been dropped.
+The D1 tables have a fixed names `tags` and `revalidations`.
+
+##### CLI
+
+The CLI was previsouly invoked as `opennextjs-cloudflare` and now takes a mandatory command:
+
+- `opennextjs-cloudflare build` is the equivalent of executing `opennextjs-cloudflare` previously
+- `opennextjs-cloudflare populateCache local` is used to populate the `local` or `remote` cache
+- `opennextjs-cloudflare preview` is used to populate the local cache and start a dev server
+- `opennextjs-cloudflare deploy` is used to populate the remote cache and deploy
diff --git a/pages/cloudflare/troubleshooting.mdx b/pages/cloudflare/troubleshooting.mdx
index b0521a5..a3ac20c 100644
--- a/pages/cloudflare/troubleshooting.mdx
+++ b/pages/cloudflare/troubleshooting.mdx
@@ -1,4 +1,3 @@
-import { SITE } from "../../config";
import { Callout } from "nextra/components";
## Troubleshooting