Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
eaffa39
split cloudflare changes
teemingc Mar 24, 2026
32054c0
Revert "split cloudflare changes"
teemingc Mar 24, 2026
85ec266
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Mar 31, 2026
f3ee124
wip
teemingc Mar 31, 2026
7e69296
fix
teemingc Apr 6, 2026
83c5f60
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 6, 2026
b202c77
fix
teemingc Apr 6, 2026
499a5c6
wip
teemingc Apr 6, 2026
8696080
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 6, 2026
bf45653
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 6, 2026
49b5bb6
docs
teemingc Apr 7, 2026
261a46a
wip
teemingc Apr 7, 2026
f181570
bump cloudflare plugin
teemingc Apr 8, 2026
3edc662
fix style inlining in workerd
teemingc Apr 8, 2026
192dfe6
format
teemingc Apr 8, 2026
79d04d5
migration docs
teemingc Apr 9, 2026
8c990a2
wip
teemingc Apr 14, 2026
e1d7ea7
i think its done now i just need to test
teemingc Apr 15, 2026
060efbd
Merge branch 'version-3' into cloudflare-vite-plugin
teemingc Apr 15, 2026
9fc12d3
super wip
teemingc Apr 17, 2026
8f067c7
analyse and prerender in environment
teemingc Apr 18, 2026
a8f81db
Merge branch 'version-3' into cloudflare-vite-plugin
teemingc Apr 18, 2026
0143e81
fixes
teemingc Apr 18, 2026
9d44c6d
yay it works
teemingc Apr 20, 2026
15e9307
format
teemingc Apr 20, 2026
c14d710
types
teemingc Apr 20, 2026
2fd5755
clean up
teemingc Apr 20, 2026
11838f9
fix cloudflare tests not running
teemingc Apr 20, 2026
b68db34
fix prerender read
teemingc Apr 20, 2026
f8fcca9
convert to typed array before passing to devalue
teemingc Apr 21, 2026
c7e9eef
better comments
teemingc Apr 21, 2026
01d879f
fix
teemingc Apr 21, 2026
1c46207
fix type issue
teemingc Apr 21, 2026
8ec2018
ensure port is up to date
teemingc Apr 21, 2026
2508934
format
teemingc Apr 21, 2026
a39ea7c
fix cloudflare build
teemingc Apr 21, 2026
2d21279
fixes
teemingc Apr 21, 2026
0303549
fix custom worker
teemingc Apr 21, 2026
97b1aec
fix dev
teemingc Apr 22, 2026
7420204
fix cloudflare dev with server deps
teemingc Apr 23, 2026
029c80f
don't use configEnvironment
teemingc Apr 23, 2026
eb05b36
default is already server implicitly
teemingc Apr 23, 2026
1ff7258
back to same node process
teemingc Apr 23, 2026
6df24c6
remove comment
teemingc Apr 23, 2026
e2c173d
Merge branch 'version-3' into cloudflare-vite-plugin
teemingc Apr 23, 2026
6f17e4e
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 23, 2026
5968607
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 23, 2026
4c782be
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 23, 2026
2124e27
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 23, 2026
502877f
docs
teemingc Apr 23, 2026
e57ea69
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 26, 2026
3b57ac2
fix docs
teemingc Apr 26, 2026
b49d74b
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 26, 2026
acfdb1b
handle assets only with new cloudflare option
teemingc Apr 27, 2026
85fca49
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 27, 2026
ed3d690
fix
teemingc Apr 27, 2026
9cd222a
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 30, 2026
4d53e59
try to fix windows path slashes
teemingc Apr 30, 2026
97bc443
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc Apr 30, 2026
733138a
fix assets only
teemingc Apr 30, 2026
2246b1a
format
teemingc Apr 30, 2026
05751cc
oops
teemingc Apr 30, 2026
9215ba4
fix test app
teemingc Apr 30, 2026
e54a194
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc May 1, 2026
3ccff3e
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc May 1, 2026
1db0223
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc May 1, 2026
5fd3b31
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc May 1, 2026
d69e335
add missing await
teemingc May 1, 2026
7c2d48f
check fallback was generated
teemingc May 2, 2026
ede2aa1
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc May 5, 2026
812cb31
use a vps version that supports server dep optimisation
teemingc May 6, 2026
b6ae3da
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc May 6, 2026
55d616f
update vps
teemingc May 7, 2026
ecc3583
fix importer url
teemingc May 7, 2026
3d53992
don't throw an error
teemingc May 7, 2026
29e1666
fix test
teemingc May 7, 2026
305ddba
Merge branch 'fetchable-dev-environment' into cloudflare-vite-plugin
teemingc May 7, 2026
3fed050
fix prerendering
teemingc May 7, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ vite.config.js.timestamp-*
.vercel_build_output
.svelte-kit
.cloudflare
.wrangler
.pnpm-debug.log
.netlify
.turbo
Expand Down
134 changes: 44 additions & 90 deletions documentation/docs/25-build-and-deploy/60-adapter-cloudflare.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
title: Cloudflare
---

To deploy to [Cloudflare Workers](https://workers.cloudflare.com/) or [Cloudflare Pages](https://pages.cloudflare.com/), use [`adapter-cloudflare`](https://github.com/sveltejs/kit/tree/main/packages/adapter-cloudflare).
To deploy to [Cloudflare Workers](https://workers.cloudflare.com/), use [`adapter-cloudflare`](https://github.com/sveltejs/kit/tree/main/packages/adapter-cloudflare).

This adapter will be installed by default when you use [`adapter-auto`](adapter-auto). If you plan on staying with Cloudflare, you can switch from [`adapter-auto`](adapter-auto) to using this adapter directly so that `event.platform` is emulated during local development, type declarations are automatically applied, and the ability to set Cloudflare-specific options is provided.
This adapter will be installed by default when you use [`adapter-auto`](adapter-auto). If you plan on staying with Cloudflare Workers, you can switch from [`adapter-auto`](adapter-auto) to using this adapter directly so that `event.platform` is emulated during local development, type declarations are automatically applied, and the ability to set Cloudflare-specific options is provided.

## Comparisons

- `adapter-cloudflare` – supports all SvelteKit features; builds for Cloudflare Workers Static Assets and Cloudflare Pages
- `adapter-cloudflare` – supports all SvelteKit features; builds for Cloudflare Workers Static Assets
- `adapter-cloudflare-workers` – deprecated. Supports all SvelteKit features; builds for Cloudflare Workers Sites
- `adapter-static` – only produces client-side static assets; compatible with Cloudflare Workers Static Assets and Cloudflare Pages

Expand All @@ -27,18 +27,9 @@ export default defineConfig({
plugins: [
sveltekit({
adapter: adapter({
// See below for an explanation of these options
config: undefined,
platformProxy: {
configPath: undefined,
environment: undefined,
persist: undefined
},
fallback: 'plaintext',
routes: {
include: ['/*'],
exclude: ['<all>']
}
// See the next section for an explanations of these options
vitePluginOptions: undefined,
worker: true
})
})
]
Expand All @@ -50,90 +41,44 @@ export default defineConfig({

## Options

### config
### vitePluginOptions

Path to your [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/). If you would like to use a Wrangler configuration filename other than `wrangler.jsonc`, `wrangler.json`, or `wrangler.toml` you can specify it using this option.
Additional preferences for the Cloudflare Vite environment. See the [Cloudflare Vite plugin API](https://developers.cloudflare.com/workers/vite-plugin/reference/api/#interface-pluginconfig) documentation for a full list of options.

### platformProxy
### worker

Preferences for the emulated `platform.env` local bindings. See the [getPlatformProxy](https://developers.cloudflare.com/workers/wrangler/api/#parameters-1) Wrangler API documentation for a full list of options.
By default, a Cloudflare Worker is alongside your application. You can turn this off if you intend to only deploy static assets. You may also want to [configure your routing](https://developers.cloudflare.com/workers/static-assets/routing/) to suit a Single Page Application (SPA) or Static Site Generation (SSG) architecture.

### fallback
## Customising your worker

Whether to render a plaintext 404.html page or a rendered SPA fallback page for non-matching asset requests.

For Cloudflare Workers, the default behaviour is to return a null-body 404-status response for non-matching assets requests. However, if the [`assets.not_found_handling`](https://developers.cloudflare.com/workers/static-assets/routing/#2-not_found_handling) Wrangler configuration setting is set to `"404-page"`, this page will be served if a request fails to match an asset. If `assets.not_found_handling` is set to `"single-page-application"`, the adapter will render a SPA fallback `index.html` page regardless of the `fallback` option specified.

For Cloudflare Pages, this page will only be served when a request that matches an entry in `routes.exclude` fails to match an asset.

Most of the time `plaintext` is sufficient, but if you are using `routes.exclude` to manually exclude a set of prerendered pages without exceeding the 100 route limit, you may wish to use `spa` instead to avoid showing an unstyled 404 page to users.

See Cloudflare Pages' [Not Found behaviour](https://developers.cloudflare.com/pages/configuration/serving-pages/#not-found-behavior) for more info.

### routes

Only for Cloudflare Pages. Allows you to customise the [`_routes.json`](https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file) file generated by `adapter-cloudflare`.

- `include` defines routes that will invoke a function, and defaults to `['/*']`
- `exclude` defines routes that will _not_ invoke a function — this is a faster and cheaper way to serve your app's static assets. This array can include the following special values:
- `<build>` contains your app's build artifacts (the files generated by Vite)
- `<files>` contains the contents of your `static` directory
- `<redirects>` contains a list of pathnames from your [`_redirects` file](https://developers.cloudflare.com/pages/configuration/redirects/) at the root
- `<prerendered>` contains a list of prerendered pages
- `<all>` (the default) contains all of the above

You can have up to 100 `include` and `exclude` rules combined. Generally you can omit the `routes` options, but if (for example) your `<prerendered>` paths exceed that limit, you may find it helpful to manually create an `exclude` list that includes `'/articles/*'` instead of the auto-generated `['/articles/foo', '/articles/bar', '/articles/baz', ...]`.

## Cloudflare Workers

### Basic configuration

When building for Cloudflare Workers, this adapter expects to find a [Wrangler configuration file](https://developers.cloudflare.com/workers/configuration/sites/configuration/) in the project root. It should look something like this:
You can customise your worker by creating a new file and specifying the path to it in your [Wrangler configuration file](https://developers.cloudflare.com/workers/configuration/sites/configuration/).

```jsonc
/// file: wrangler.jsonc
{
"name": "<any-name-you-want>",
"main": ".svelte-kit/cloudflare/_worker.js",
"compatibility_flags": ["nodejs_als"],
"compatibility_date": "<YYYY-MM-DD>",
"assets": {
"binding": "ASSETS",
"directory": ".svelte-kit/cloudflare",
}
"main": "src/worker.js",
}
```

### Deployment

You can use the Wrangler CLI to deploy your application by running `npx wrangler deploy` or use the [Cloudflare Git integration](https://developers.cloudflare.com/workers/ci-cd/builds/) to enable automatic builds and deployments on push.

## Cloudflare Pages

### Deployment

Please follow the [Get Started Guide](https://developers.cloudflare.com/pages/get-started/) for Cloudflare Pages to begin.

If you're using the [Git integration](https://developers.cloudflare.com/pages/get-started/git-integration/), your build settings should look like this:
Inside your worker file, you can reproduce the SvelteKit request handling behaviour by importing the `fetch` method from `@sveltejs/adapter-cloudflare/worker`.

- Framework preset – SvelteKit
- Build command – `npm run build` or `vite build`
- Build output directory – `.svelte-kit/cloudflare`


Once configured, go to the **Runtime** section of your project settings, and add the `nodejs_als` compatibility flag to enable the [Node.js AsyncLocalStorage](https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-asynclocalstorage). Alternatively, do this in your wrangler config using the `compatibility_flags` array.

### Further reading
```js
/// file: src/worker.js
import { fetch } from '@sveltejs/adapter-cloudflare/worker';

You may wish to refer to [Cloudflare's documentation for deploying a SvelteKit site on Cloudflare Pages](https://developers.cloudflare.com/pages/framework-guides/deploy-a-svelte-kit-site/).
export default {
fetch
// Add other types of handlers here
}
```

### Notes
## Deployment

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/).
You can use the Wrangler CLI to deploy your application by running `npx wrangler deploy` or use the [Cloudflare Git integration](https://developers.cloudflare.com/workers/ci-cd/builds/) to enable automatic builds and deployments on push.

## 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:
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:

```js
// @filename: ambient.d.ts
Expand All @@ -160,19 +105,26 @@ export async function POST({ request, platform }) {

> [!NOTE] SvelteKit's built-in [`$env` module]($env-static-private) should be preferred for environment variables.

To make these types available to your app, install [`@cloudflare/workers-types`](https://www.npmjs.com/package/@cloudflare/workers-types) and reference them in your `src/app.d.ts`:
After configuring the bindings in your Wrangler configuration file, you can add type-safety by running [`npx wrangler types`](https://developers.cloudflare.com/workers/languages/typescript/) and adding the generated types to your `tsconfig.json`.

```json
/// file: tsconfig.json
{
"compilerOptions": {
+++"types": ["worker-configuration.d.ts"]+++
}
}
```

Finally, add `Env` to the `platform.env` property in `src/app.d.ts`:

```ts
// @errors: 2304
/// file: src/app.d.ts
+++import { KVNamespace, DurableObjectNamespace } from '@cloudflare/workers-types';+++

declare global {
namespace App {
interface Platform {
+++ env: {
YOUR_KV_NAMESPACE: KVNamespace;
YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace;
};+++
+++ env: Env;+++
}
}
}
Expand All @@ -182,9 +134,7 @@ export {};

### Testing locally

Cloudflare specific values in the `platform` property are emulated during dev and preview modes. Local [bindings](https://developers.cloudflare.com/workers/wrangler/configuration/#bindings) are created based on your [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/) and are used to populate `platform.env` during development and preview. Use the adapter config [`platformProxy` option](#Options-platformProxy) to change your preferences for the bindings.

For testing the build, you should use [Wrangler](https://developers.cloudflare.com/workers/wrangler/) version 4. Once you have built your site, run `wrangler dev .svelte-kit/cloudflare/_worker.js` if you're testing for Cloudflare Workers or `wrangler pages dev .svelte-kit/cloudflare` for Cloudflare Pages.
Cloudflare specific values in the `platform` property are emulated during dev and preview modes through [Cloudflare's Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/). [Bindings](https://developers.cloudflare.com/workers/wrangler/configuration/#bindings) are created based on your [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/) and are used to populate `platform.env`.

## Headers and redirects

Expand Down Expand Up @@ -217,6 +167,10 @@ Instead, use the [`read`]($app-server#read) function from `$app/server` to acces

Alternatively, you can [prerender](page-options#prerender) the routes in question.

## Migrating from Pages

Cloudflare Workers is now preferred over Pages because of its broader feature set. You should follow the [official migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/) to redeploy your project to Workers before deleting your Pages project.

## Migrating from Workers Sites

Cloudflare no longer recommends using [Workers Sites](https://developers.cloudflare.com/workers/configuration/sites/configuration/) and instead recommends using [Workers Static Assets](https://developers.cloudflare.com/workers/static-assets/). To migrate, replace `@sveltejs/adapter-cloudflare-workers` with `@sveltejs/adapter-cloudflare` and remove all `site` configuration settings from your Wrangler configuration file, then add the `assets.directory` and `assets.binding` configuration settings:
Expand Down
1 change: 0 additions & 1 deletion packages/adapter-cloudflare/.gitignore

This file was deleted.

3 changes: 2 additions & 1 deletion packages/adapter-cloudflare/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import {

declare global {
namespace App {
// TODO: consider removing these in favour of users importing them directly from `cloudflare:workers`
export interface Platform {
env: unknown;
ctx: ExecutionContext;
caches: CacheStorage;
cf?: IncomingRequestCfProperties;
cf: IncomingRequestCfProperties;
}
}
}
71 changes: 18 additions & 53 deletions packages/adapter-cloudflare/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,44 @@
import { PluginConfig } from '@cloudflare/vite-plugin';
import { Adapter } from '@sveltejs/kit';
import './ambient.js';
import { GetPlatformProxyOptions } from 'wrangler';

export default function plugin(options?: AdapterOptions): Adapter;

export interface AdapterOptions {
/**
* Path to your [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/).
* Options to pass to the Cloudflare Vite plugin.
* @see https://developers.cloudflare.com/workers/vite-plugin/reference/api/#interface-pluginconfig
*/
config?: string;
vitePluginOptions?: PluginConfig;
/**
* Whether to deploy a Cloudflare Worker or static assets only.
* @default true
*/
worker?: boolean;
/**
* Whether to render a plaintext 404.html page or a rendered SPA fallback page
* for non-matching asset requests.
*
* For Cloudflare Workers, the default behaviour is to return a null-body
* The default behaviour is to return a null-body
* 404-status response for non-matching assets requests. However, if the
* [`assets.not_found_handling`](https://developers.cloudflare.com/workers/static-assets/routing/#2-not_found_handling)
* Wrangler configuration setting is set to `"404-page"`, this page will be
* served if a request fails to match an asset. If `assets.not_found_handling`
* is set to `"single-page-application"`, the adapter will render a SPA fallback
* `index.html` page regardless of the `fallback` option specified.
*
* For Cloudflare Pages, this page will only be served when a request that
* matches an entry in `routes.exclude` fails to match an asset.
*
* Most of the time `plaintext` is sufficient, but if you are using `routes.exclude` to manually
* exclude a set of prerendered pages without exceeding the 100 route limit, you may wish to
* use `spa` instead to avoid showing an unstyled 404 page to users.
*
* See [Cloudflare Pages' Not Found behavior](https://developers.cloudflare.com/pages/configuration/serving-pages/#not-found-behavior) for more info.
*
* @default 'plaintext'
* @deprecated removed in 8.0.0. Configure `assets.not_found_handling` in your Wrangler configuration file instead
*/
fallback?: 'plaintext' | 'spa';

/**
* Only for Cloudflare Pages. Customize the automatically-generated [`_routes.json`](https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file) file.
*/
routes?: {
/**
* Routes that will be invoked by functions. Accepts wildcards.
* @default ["/*"]
*/
include?: string[];

/**
* Routes that will not be invoked by functions. Accepts wildcards.
* `exclude` takes priority over `include`.
*
* To have the adapter automatically exclude certain things, you can use these placeholders:
*
* - `<build>` to exclude build artifacts (files generated by Vite)
* - `<files>` for the contents of your `static` directory
* - `<prerendered>` for prerendered routes
* - `<all>` to exclude all of the above
*
* @default ["<all>"]
*/
exclude?: string[];
};

/**
* Config object passed to [`getPlatformProxy`](https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy)
* during development and preview.
* @deprecated removed in 8.0.0. Use `vitePluginOptions` instead
*/
platformProxy?: GetPlatformProxyOptions;
}

/**
* The JSON format of the {@link https://developers.cloudflare.com/pages/functions/routing/#create-a-_routesjson-file | `_routes.json`}
* file that controls when the Cloudflare Pages Function is invoked.
*/
export interface RoutesJSONSpec {
version: 1;
description: string;
include: string[];
exclude: string[];
platformProxy?: Record<string, any>;
/**
* Path to your [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/).
* @deprecated removed in 8.0.0. Use `vitePluginOptions.configPath` instead
*/
config?: string;
}
Loading
Loading