Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
30d1f46
feat: use the new Workers Static Assets feature from Cloudflare
petebacondarwin Nov 28, 2024
2ae3029
Merge branch 'main' into pr/petebacondarwin/13072
teemingc Dec 31, 2024
a294804
Merge branch 'main' into pr/petebacondarwin/13072
teemingc Jan 21, 2025
b667ac7
upgrade workers types
teemingc Jan 21, 2025
8a0cb79
docs: apply review feedback
astralhpi Feb 6, 2025
65bc106
refactor: fix naming to match convention
astralhpi Feb 6, 2025
a824faf
docs: simplify CHANGELOG for Workers Assets migration
astralhpi Feb 6, 2025
094cc0f
docs: add migration guide for Workers Static Assets
astralhpi Feb 6, 2025
e81980e
Merge branch 'main' into update-cloudflare-worker-assets-handling
astralhpi Feb 6, 2025
7943188
fix: lock file
astralhpi Feb 6, 2025
59495bb
docs: fix mistake
astralhpi Feb 7, 2025
b278361
docs: update Wrangler version requirement to v3.87.0+
astralhpi Feb 7, 2025
60d0c2b
Merge branch 'main' into update-cloudflare-worker-assets-handling
astralhpi Mar 9, 2025
f5f7445
Merge branch 'main' into pr/astralhpi/13427
teemingc Mar 19, 2025
6838afa
cleanup and parity with cloudflare pages adapter
teemingc Mar 20, 2025
13128a9
move comparisons to cloudflare workers page
teemingc Mar 20, 2025
4d952a3
changesets
teemingc Mar 20, 2025
cb73dd8
fix lint
teemingc Mar 20, 2025
ccb0242
serve immutable assets from worker with cache control
teemingc Mar 20, 2025
071f62f
changesets
teemingc Mar 20, 2025
5bd2e39
add static headers and redirects
teemingc Mar 20, 2025
c13390a
Merge branch 'main' into pr/astralhpi/13427
teemingc Mar 20, 2025
578638c
Merge branch 'main' into pr/astralhpi/13427
teemingc Mar 20, 2025
94b7b73
add support for _headers and _redirects
teemingc Mar 20, 2025
4dde235
Merge branch 'main' into pr/astralhpi/13427
teemingc Mar 21, 2025
909c2e7
specify value of assets.binding config
teemingc Mar 21, 2025
2b08bd3
add migration example
teemingc Mar 21, 2025
906c110
error if site key is in wrangler config
teemingc Mar 21, 2025
26fbbbf
revert removing x-robots-tag: noindex from headers
teemingc Mar 24, 2025
68a214a
copy to _worker.js file instead of dir
teemingc Mar 24, 2025
fefc761
Merge branch 'main' into pr/astralhpi/13427
teemingc Mar 24, 2025
e7f3bf8
format
teemingc Mar 24, 2025
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
19 changes: 19 additions & 0 deletions .changeset/smart-owls-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@sveltejs/adapter-cloudflare-workers': major
---

feat: use the new Workers Static Assets feature from Cloudflare

This changes the adapter to stop using the old Workers Sites (kv-asset-handler) approach in favor of the new Workers Static Assets feature, which is embedded into Cloudflare natively.

Also, this change removes the extra esbuild step that was being run inside the adapter, instead relying upon Wrangler to do the bundling.

## Breaking changes and migration

- This version of the adapter requires Wrangler version 3.87.0 or later.

Run `npm add -D wrangler@latest` (or similar) in your project to update Wrangler.

- The user's Wrangler configuration (`wrangler.toml`) must be migrated from using Workers Sites to using Workers Assets.

For reference, see the previous [Workers Sites documentation](https://developers.cloudflare.com/workers/configuration/sites/configuration/) and the new [Workers Assets documentation](NEW_DOC_URL).
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ title: Cloudflare Workers

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

> [!NOTE] Unless you have a specific reason to use `adapter-cloudflare-workers`, it's recommended that you use `adapter-cloudflare` instead. Both adapters have equivalent functionality, but Cloudflare Pages offers features like GitHub integration with automatic builds and deploys, preview deployments, instant rollback and so on.
> [!NOTE] Cloudflare is actively working to bridge the gaps between Workers and Pages and is providing ways to migrate Pages projects to Workers. Many features of Cloudflare Pages are now available in Workers, with Beta support for additional functionality.
>
> Both Workers and Pages remain valid options, and the best choice depends on your specific needs. Review the latest feature parity in the [compatibility matrix](https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/) to determine the best fit for your project.

## Usage

Expand Down Expand Up @@ -42,20 +44,23 @@ Preferences for the emulated `platform.env` local bindings. See the [getPlatform

## Basic Configuration

This adapter expects to find a [wrangler.toml/wrangler.json](https://developers.cloudflare.com/workers/platform/sites/configuration) file in the project root. It should look something like this:
This adapter expects to find a [wrangler.toml/wrangler.toml](https://developers.cloudflare.com/workers/platform/sites/configuration) file in the project root. It should look something like this:

```toml
/// file: wrangler.toml
name = "<your-service-name>"
account_id = "<your-account-id>"

main = "./.cloudflare/worker.js"
site.bucket = "./.cloudflare/public"

build.command = "npm run build"

compatibility_date = "2021-11-12"
compatibility_date = "2025-01-01"
workers_dev = true

[assets]
directory = "./.cloudflare/public"
binding = "ASSETS"
```

`<your-service-name>` can be anything. `<your-account-id>` can be found by logging into your [Cloudflare dashboard](https://dash.cloudflare.com) and grabbing it from the end of the URL:
Expand Down Expand Up @@ -138,3 +143,63 @@ When deploying to workers, the server generated by SvelteKit is bundled into a s
### Accessing the file system

You can't use `fs` in Cloudflare Workers — you must [prerender](page-options#prerender) the routes in question.



## Migrating from Workers Sites to Workers Static Assets

Cloudflare no longer recommends using Workers Sites. See the official deprecation notice:
➡ [Workers Sites Documentation (Deprecated)](https://developers.cloudflare.com/workers/configuration/sites/configuration/)

Users should migrate to Workers Static Assets for improved performance and maintainability.
➡ [Workers Static Assets Documentation](https://developers.cloudflare.com/workers/static-assets/)

This guide provides key information for updating your configuration.

### Update `wrangler.toml`

Replace the **Workers Sites** configuration:

```toml
# Previous Workers Sites configuration
name = "<your-site-name>"
account_id = "<your-account-id>"
compatibility_date = "2021-11-12"
main = "./.cloudflare/worker.js"

site.bucket = "./.cloudflare/public"
```

With the Workers Static Assets configuration:

```toml
# New Workers Static Assets configuration
name = "<your-site-name>"
account_id = "<your-account-id>"
compatibility_date = "2025-01-01"
main = "./.cloudflare/worker.js"

[assets]
directory = "./.cloudflare/public"
binding = "ASSETS"
```

The `site.bucket` property is no longer needed and should be removed.

### Asset Serving Behavior Change

In Workers Sites (used with `adapter-cloudflare-workers`), assets were served through the Worker, allowing custom headers such as:
- `cache-control`
- `content-type`
- `x-robots-tag`

However, **Workers Static Assets serves assets directly by default**, bypassing the Worker execution. As a result, these custom headers are no longer applied automatically. Instead, assets now rely on **ETag-based caching** for optimization.

If you need to retain the previous behavior and ensure the Worker runs for every request (allowing custom headers), you can disable direct asset serving:

```toml
[assets]
directory = "./.cloudflare/public"
binding = "ASSETS"
serve_directly = false
```
2 changes: 1 addition & 1 deletion packages/adapter-cloudflare-workers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

SvelteKit adapter that creates a Cloudflare Workers site using a function for dynamic server rendering.

**Requires [Wrangler v2](https://developers.cloudflare.com/workers/wrangler/get-started/).** Wrangler v1 is no longer supported.
**Requires [Wrangler v3 or later](https://developers.cloudflare.com/workers/wrangler/get-started/).**.

## Docs

Expand Down
9 changes: 0 additions & 9 deletions packages/adapter-cloudflare-workers/files/_package.json

This file was deleted.

45 changes: 6 additions & 39 deletions packages/adapter-cloudflare-workers/files/entry.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { Server } from 'SERVER';
import { manifest, prerendered, base_path } from 'MANIFEST';
import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler';
import static_asset_manifest_json from '__STATIC_CONTENT_MANIFEST';
const static_asset_manifest = JSON.parse(static_asset_manifest_json);

const server = new Server(manifest);

Expand All @@ -25,7 +22,7 @@ export default {
// static assets
if (url.pathname.startsWith(app_path)) {
/** @type {Response} */
const res = await get_asset_from_kv(req, env, context);
const res = await env.ASSETS.fetch(req);
if (is_error(res.status)) return res;

const cache_control = url.pathname.startsWith(immutable)
Expand Down Expand Up @@ -65,20 +62,11 @@ export default {

let location = pathname.at(-1) === '/' ? stripped_pathname : pathname + '/';

if (
is_static_asset ||
prerendered.has(pathname) ||
pathname === version_file ||
pathname.startsWith(immutable)
) {
return get_asset_from_kv(req, env, context, (request, options) => {
if (prerendered.has(pathname)) {
url.pathname = '/' + prerendered.get(pathname).file;
return new Request(url.toString(), request);
}

return mapRequestToAsset(request, options);
});
if (prerendered.has(pathname)) {
url.pathname = '/' + prerendered.get(pathname).file;
return env.ASSETS.fetch(new Request(url.toString(), req));
} else if (is_static_asset || pathname === version_file || pathname.startsWith(immutable)) {
return env.ASSETS.fetch(req);
} else if (location && prerendered.has(location)) {
if (search) location += search;
return new Response('', {
Expand Down Expand Up @@ -106,27 +94,6 @@ export default {
}
};

/**
* @param {Request} req
* @param {any} env
* @param {any} context
*/
async function get_asset_from_kv(req, env, context, map = mapRequestToAsset) {
return await getAssetFromKV(
{
request: req,
waitUntil(promise) {
return context.waitUntil(promise);
}
},
{
ASSET_NAMESPACE: env.__STATIC_CONTENT,
ASSET_MANIFEST: static_asset_manifest,
mapRequestToAsset: map
}
);
}

/**
* @param {number} status
* @returns {boolean}
Expand Down
Loading
Loading