From f69fdf580ed97d8c9fa51b11c6c5118faf2339fd Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Tue, 24 Jun 2025 16:44:56 +0200 Subject: [PATCH] docs(cloudflare): skew protection --- pages/cloudflare/howtos/_meta.json | 3 +- pages/cloudflare/howtos/skew.mdx | 79 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 pages/cloudflare/howtos/skew.mdx diff --git a/pages/cloudflare/howtos/_meta.json b/pages/cloudflare/howtos/_meta.json index c8fe30e..5a98a13 100644 --- a/pages/cloudflare/howtos/_meta.json +++ b/pages/cloudflare/howtos/_meta.json @@ -6,5 +6,6 @@ "image": "Image Optimization", "custom-worker": "Custom Worker", "keep_names": "__name issues", - "workerd": "workerd specific packages" + "workerd": "workerd specific packages", + "skew": "Skew Protection" } diff --git a/pages/cloudflare/howtos/skew.mdx b/pages/cloudflare/howtos/skew.mdx new file mode 100644 index 0000000..a75c545 --- /dev/null +++ b/pages/cloudflare/howtos/skew.mdx @@ -0,0 +1,79 @@ +import { Callout } from "nextra/components"; + +## Skew protection + +The Cloudflare adapter has _experimental support_ for skew protection based on [the preview URLs](https://developers.cloudflare.com/workers/configuration/previews/). + + + Preview URLs are disabled for [Workers that implement a Durable + Object](https://developers.cloudflare.com/workers/configuration/previews/#limitations). If your app uses + Durable Objects, they will need to be implemented in a separate Worker. + + +### How to enable the skew protection + +**OpenNext config** + +Set `cloudflare.skewProtectionEnabled` to `true` to enable skew protection. + +```ts +// open-next.config.ts +export default { + // ... + cloudflare: { + skewProtectionEnabled: true, + }, +} satisfies OpenNextConfig; +``` + +**Wrangler configuration** + +The Worker needs to serve the correct version of the app assets. For that it need be be executed before incoming requests are matched against the assets. Set [`run_worker_first`](https://developers.cloudflare.com/workers/static-assets/binding/#run_worker_first) in your wrangler configuration to enable this behavior: + +```jsonc +// wrangler.jsonc +{ + "name": "my-app", + // ... + "assets": { + "directory": ".open-next/assets", + "binding": "ASSETS", + "run_worker_first": true, + }, + // ... +} +``` + +**Environment variables** + +The following environment variables should be set when the skew protection is use: + +- `CF_WORKER_NAME` should be set to the name of the worker, i.e. `my-app` given the config above +- `CF_PREVIEW_DOMAIN` is the the subdomain of `workers.dev` where the previews are deployed, i.e. `..workers.dev` +- `CF_WORKERS_SCRIPTS_API_TOKEN` is an API token with the `Workers Scripts:Read` permission +- `CF_ACCOUNT_ID` is the Cloudflare account id where the app is deployed. + +Those variables are used to retrieve the past deployments of your application before the app is deployed. + +**Next config** + +You must set a different `deploymentId` in your next config each time your app is deployed. You will get an error if the `deployementId` has already been used when deploying. + +The cloudflare adapter exports a `getDeploymentId()` function that can be used to generate a unique deployment id. + +```ts +// next.config.ts +import { getDeploymentId } from "@opennextjs/cloudflare"; + +const nextConfig = { + // ... + deploymentId: getDeploymentId(), +}; +``` + +### What you should know + +- Because the Worker is configured to run in front of the assets Worker (`run_worker_first`), requesting an asset will count as a request to your Worker +- Requesting an older deployment will generate 2 requests: the request to the latest version and the request to the older version +- It is not currently possible to delete a deployment +- Requests to an older deployement will be a few milli-seconds slower than requests to the latest version of the app