Skip to content

Commit c9fce20

Browse files
vicbconico974james-elicx
authored
docs(cloudflare): skew protection, static assets (#164)
Co-authored-by: conico974 <[email protected]> Co-authored-by: James Anderson <[email protected]>
1 parent 215885f commit c9fce20

File tree

3 files changed

+147
-1
lines changed

3 files changed

+147
-1
lines changed

pages/cloudflare/howtos/_meta.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66
"image": "Image Optimization",
77
"custom-worker": "Custom Worker",
88
"keep_names": "__name issues",
9-
"workerd": "workerd specific packages"
9+
"workerd": "workerd specific packages",
10+
"skew": "Skew Protection",
11+
"assets": "Static assets"
1012
}

pages/cloudflare/howtos/assets.mdx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Static assets (public folder)
2+
3+
The [static assets of Next located in the public folder](https://nextjs.org/docs/app/api-reference/file-conventions/public-folder) are served using [Workers Static Assets](https://developers.cloudflare.com/workers/static-assets/).
4+
5+
Workers Static Assets can intercept requests to the application ([`run_worker_first=false`](https://developers.cloudflare.com/workers/static-assets/) which is the default). This is the most cost efficient option as asset requests will not be billed in that case.
6+
7+
Another option is to run the Worker first (`run_worker_first=true`) to offer more flexibility at the expense of a higher cost.
8+
9+
Note that `run_worker_first` could also be set to a list of patterns - this is a great option if you need more flexibility for only a subset of the statids assets.
10+
11+
### run_worker_first=false
12+
13+
When `run_worker_first` is set to `false`, requests are intercepted before reaching the worker and are not billed:
14+
15+
```jsonc
16+
// wrangler.jsonc
17+
{
18+
"name": "my-app",
19+
// ...
20+
"assets": {
21+
"directory": ".open-next/assets",
22+
"binding": "ASSETS",
23+
// Optional as false is the default value
24+
"run_worker_first": false,
25+
},
26+
// ...
27+
}
28+
```
29+
30+
This is the most cost efficient option to use when you do not need to serve assets behind the middleware or Next rewrites and headers from [the Next config](https://nextjs.org/docs/app/api-reference/config/next-config-js).
31+
32+
When `run_worker_first=false` you can still configure [headers](https://developers.cloudflare.com/workers/static-assets/headers/) and [redirects](https://developers.cloudflare.com/workers/static-assets/redirects/) via Worker Static Assets.
33+
34+
### run_worker_first=true
35+
36+
When `run_worker_first` is set to `true`, all the requests will reach the Worker and be billed:
37+
38+
```jsonc
39+
// wrangler.jsonc
40+
{
41+
"name": "my-app",
42+
// ...
43+
"assets": {
44+
"directory": ".open-next/assets",
45+
"binding": "ASSETS",
46+
"run_worker_first": true,
47+
},
48+
// ...
49+
}
50+
```
51+
52+
The Open Next asset resolver will be used to retrieve the assets from the Worker.
53+
54+
When `run_worker_first=true`, assets are served behind the middleware and Next rewrites and headers from [the Next config](https://nextjs.org/docs/app/api-reference/config/next-config-js). The [headers](https://developers.cloudflare.com/workers/static-assets/headers/) and [redirects](https://developers.cloudflare.com/workers/static-assets/redirects/) configured for the Worker Static Assets do not apply in this case.
55+
56+
`run_worker_first=true` should be used if you plan to use skew protection.

pages/cloudflare/howtos/skew.mdx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { Callout } from "nextra/components";
2+
3+
## Skew protection
4+
5+
The Cloudflare adapter has _experimental support_ for skew protection based on [the preview URLs](https://developers.cloudflare.com/workers/configuration/previews/).
6+
7+
<Callout type="info">
8+
Preview URLs are disabled for [Workers that implement a Durable
9+
Object](https://developers.cloudflare.com/workers/configuration/previews/#limitations). If your app uses
10+
Durable Objects, they will need to be implemented in a separate Worker.
11+
</Callout>
12+
13+
### How to enable the skew protection
14+
15+
**OpenNext config**
16+
17+
Set `cloudflare.skewProtection.enabled` to `true` to enable skew protection:
18+
19+
```ts
20+
// open-next.config.ts
21+
export default {
22+
// ...
23+
cloudflare: {
24+
skewProtection: {
25+
enabled: true,
26+
// Maximum number of previous versions to use.
27+
// Optional, default to 20.
28+
maxNumberOfVersions: 20,
29+
// Age of the oldest version to use (from the last deplyment date)
30+
// Optional, default to 7 days.
31+
maxVersionAgeDays: 7,
32+
},
33+
},
34+
} satisfies OpenNextConfig;
35+
```
36+
37+
**Wrangler configuration**
38+
39+
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) to `true` in your wrangler configuration to enable this behavior:
40+
41+
```jsonc
42+
// wrangler.jsonc
43+
{
44+
"name": "my-app",
45+
// ...
46+
"assets": {
47+
"directory": ".open-next/assets",
48+
"binding": "ASSETS",
49+
"run_worker_first": true,
50+
},
51+
// ...
52+
}
53+
```
54+
55+
**Environment variables**
56+
57+
The following environment variables should be set when the skew protection is used:
58+
59+
- `CF_WORKER_NAME` should be set to the name of the worker, i.e. `my-app` given the config above. If you're using environment, the name of the app should contain your env, i.e. `my-app-<env>`
60+
- `CF_PREVIEW_DOMAIN` is the the subdomain of `workers.dev` where the previews are deployed, i.e. `<version-name>.<domain>.workers.dev`
61+
- `CF_WORKERS_SCRIPTS_API_TOKEN` is an API token with the `Workers Scripts:Read` permission
62+
- `CF_ACCOUNT_ID` is the Cloudflare account id where the app is deployed.
63+
64+
Those variables are used to retrieve the past deployments of your application.
65+
66+
**Next config**
67+
68+
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 by a previous deployment.
69+
70+
The cloudflare adapter exports a `getDeploymentId()` function that can be used to generate a unique deployment id.
71+
72+
```ts
73+
// next.config.ts
74+
import { getDeploymentId } from "@opennextjs/cloudflare";
75+
76+
const nextConfig = {
77+
// ...
78+
deploymentId: getDeploymentId(),
79+
};
80+
```
81+
82+
### What you should know
83+
84+
- 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
85+
- Requesting an older deployment will generate 2 requests: the request to the latest version and the request to the older version
86+
- It is not currently possible to delete a deployment
87+
- Requests to an older deployment will be a few milli-seconds slower than requests to the latest version of the app
88+
- Request to a deployment older than the `maxNumberOfVersions` or older than `maxVersionAgeDays` will fallback to the current deployment

0 commit comments

Comments
 (0)