Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/true-places-make.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-cloudflare': major
---

breaking: require `nodejs_als` compatibility flag
27 changes: 16 additions & 11 deletions documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ When building for Cloudflare Workers, this adapter expects to find a [Wrangler c
"name": "<any-name-you-want>",
"main": ".svelte-kit/cloudflare/_worker.js",
"compatibility_date": "2025-01-01",
"compatibility_flags": ["nodejs_als"],
"assets": {
"binding": "ASSETS",
"directory": ".svelte-kit/cloudflare",
Expand All @@ -102,6 +103,8 @@ Please follow the [framework guide](https://developers.cloudflare.com/workers/fr

## Cloudflare Pages

Ensure that you have enabled the `nodejs_als` compatibility flag in your dashboard, or via your Wrangler configuration.

### Deployment

Please follow the [Get Started Guide](https://developers.cloudflare.com/pages/get-started/) for Cloudflare Pages to begin.
Expand All @@ -120,6 +123,19 @@ You may wish to refer to [Cloudflare's documentation for deploying a SvelteKit s

Functions contained in the [`/functions` directory](https://developers.cloudflare.com/pages/functions/routing/) at the project's root will _not_ be included in the deployment. Instead, functions should be implemented as [server endpoints](routing#server) in your SvelteKit app, which is compiled to a [single `_worker.js` file](https://developers.cloudflare.com/pages/functions/advanced-mode/).

## Node compatibility

SvelteKit uses the [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage) API internally. You need to enable the `nodejs_als` [compatibility flag](https://developers.cloudflare.com/workers/runtime-apis/nodejs/), either via the Cloudflare dashboard (if using Pages) or your Wrangler configuration, or your app may break in production.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this says you need to enable it via the dashboard or config file, but it looks like the code will error if it's not in the config file, so maybe we should drop the reference to the dashboard here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, I've remembered why I hesitated to put this PR up — it's entirely possible that you've set the flag via the dashboard and so don't need the config file at all. The way this should work is that the framework should be able to configure this stuff on the user's behalf but I don't think that exists on Cloudflare

So maybe it should only error for workers, and be a warning for pages? Ugh

Copy link
Member

@teemingc teemingc Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way this should work is that the framework should be able to configure this stuff on the user's behalf but I don't think that exists on Cloudflare

I've talked to the Cloudflare folks and the recommended way to handle this is through a generated Wrangler config: https://developers.cloudflare.com/workers/wrangler/configuration/#generated-wrangler-configuration . I'm not a big fan of it though as it requires duplicating the user's config since it doesn't extend an existing one. Duplicating can also get tricky because any relative paths set need to be changed to resolve from where the generated config is instead of where the original config is.

Copy link
Member

@teemingc teemingc Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SvelteKit uses the [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage) API internally. You need to enable the `nodejs_als` [compatibility flag](https://developers.cloudflare.com/workers/runtime-apis/nodejs/), either via the Cloudflare dashboard (if using Pages) or your Wrangler configuration, or your app may break in production.
SvelteKit uses the [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage) API internally. You need to enable the `nodejs_als` [compatibility flag](https://developers.cloudflare.com/workers/runtime-apis/nodejs/) via your Wrangler configuration, or your app may break in production.

It may be better to force Cloudflare Pages users to have a Wrangler configuration since it's required when migrating to Cloudflare Workers anyway. Also makes it easier for us since we can't detect dashboard settings during a local build.


```jsonc
/// file: wrangler.jsonc
{
"compatibility_flags": ["nodejs_als"]
}
```

If you app makes use of other Node.js APIs such as `node:path`, enable support via the `nodejs_compat` compatibility flag instead.

## Runtime APIs

The [`env`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#parameters) object contains your project's [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/), which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the `platform` property, along with [`ctx`](https://developers.cloudflare.com/workers/runtime-apis/context/), [`caches`](https://developers.cloudflare.com/workers/runtime-apis/cache/), and [`cf`](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties), meaning that you can access it in hooks and endpoints:
Expand Down Expand Up @@ -167,17 +183,6 @@ However, they will have no effect on responses dynamically rendered by SvelteKit

## Troubleshooting

### Node.js compatibility

If you would like to enable [Node.js compatibility](https://developers.cloudflare.com/workers/runtime-apis/nodejs/), you can add the `nodejs_compat` compatibility flag to your Wrangler configuration file:

```jsonc
/// file: wrangler.jsonc
{
"compatibility_flags": ["nodejs_compat"]
}
```

### Worker size limits

When deploying your application, the server generated by SvelteKit is bundled into a single file. Wrangler will fail to publish your worker if it exceeds [the size limits](https://developers.cloudflare.com/workers/platform/limits/#worker-size) after minification. You're unlikely to hit this limit usually, but some large libraries can cause this to happen. In that case, you can try to reduce the size of your worker by only importing such libraries on the client side. See [the FAQ](./faq#How-do-I-use-a-client-side-library-accessing-document-or-window) for more information.
Expand Down
16 changes: 16 additions & 0 deletions packages/adapter-cloudflare/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,22 @@ function validate_wrangler_config(config_file = undefined) {
validate_worker_settings(wrangler_config);
}

const flags = wrangler_config?.compatibility_flags ?? [];

if (flags.includes('nodejs_compat') && flags.includes('nodejs_als')) {
Copy link
Member

@teemingc teemingc Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check that a main key is specified in the config too so that it's only needed if a user is deploying a Worker. I've met some folks who are only using the Cloudflare adapter for static sites / single-page apps. The docs should also mention something similar

const file = config_file
? path.relative(process.cwd(), config_file)
: 'your wrangler configuration';

throw new Error(
`\u001B\u001B[31m` +
`\nPlease add the "nodejs_als" compatibility flag to ${file}, as SvelteKit uses the AsyncLocalStorage API and your app may break in production without it.\n\n` +
`Alternatively, if you are using Node APIs in your app, you should add the "nodejs_compat" flag.\n\n` +
`For more information on compatibility flags see https://svelte.dev/docs/kit/adapter-cloudflare#Node-compatibility.\n` +
`\u001B[39m\u001B`
);
}

return wrangler_config;
}

Expand Down
3 changes: 3 additions & 0 deletions packages/adapter-cloudflare/test/apps/pages/wrangler.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"compatibility_flags": ["nodejs_als"]
}
3 changes: 3 additions & 0 deletions packages/adapter-cloudflare/test/apps/workers/wrangler.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"compatibility_flags": ["nodejs_als"]
}
Loading