Skip to main content

Cloudflare Workers

To deploy to Cloudflare Workers, use adapter-cloudflare-workers.

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.

Usage

Install with npm i -D @sveltejs/adapter-cloudflare-workers, then add the adapter to your svelte.config.js:

svelte.config
import import adapteradapter from '@sveltejs/adapter-cloudflare-workers';

export default {
	
kit: {
    adapter: any;
}
kit
: {
adapter: anyadapter: import adapteradapter({ // see below for options that can be set here }) } };

Options

config

Path to your Wrangler configuration file. If you would like to use a Wrangler configuration filename other than wrangler.jsonc, you can specify it using this option.

handlers

Path to a file with additional handlers export alongside the SvelteKit-generated fetch() handler. Enables integration of, for example, scheduled() or queue() handlers with your SvelteKit app.

Default: undefined- no additional handlers are exported.

The handlers file should export a default object with any additional handlers. Example below:

src/handlers
export default {
  async function scheduled(event: any, env: any, ctx: any): Promise<void>scheduled(event, env, ctx) {


	var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
("Scheduled trigger!");
}, // additional handlers go here }

The adapter expects the handlers file to have a default export.

The adapter will overwrite any fetch handler exported from the handlers file in the generated worker. Most uses for a fetch handler are covered by endpoints or server hooks, so you should use those instead.

platformProxy

Preferences for the emulated platform.env local bindings. See the getPlatformProxy Wrangler API documentation for a full list of options.

Basic Configuration

This adapter expects to find a Wrangler configuration file in the project root. It should look something like this:

wrangler
{
	"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"
}

<your-service-name> can be anything. <your-account-id> can be found by running wrangler whoami using the Wrangler CLI tool or by logging into your Cloudflare dashboard and grabbing it from the end of the URL:

https://dash.cloudflare.com/<your-account-id>/home

You should add the .cloudflare directory (or whichever directories you specified for main and site.bucket) and the .wrangler directory to your .gitignore.

You will need to install Wrangler and log in, if you haven’t already:

npm i -D wrangler
wrangler login

Then, you can build your app and deploy it:

wrangler deploy

Runtime APIs

The env object contains your project’s bindings, which consist of KV/DO namespaces, etc. It is passed to SvelteKit via the platform property, along with context, caches, and cf, meaning that you can access it in hooks and endpoints:

export async function 
function POST({ request, platform }: {
    request: any;
    platform: any;
}): Promise<void>
POST
({ request, platform }) {
const const x: anyx = platform: anyplatform.env.YOUR_DURABLE_OBJECT_NAMESPACE.idFromName('x'); }

SvelteKit’s built-in $env module should be preferred for environment variables.

To make these types available to your app, install @cloudflare/workers-types and reference them in your src/app.d.ts:

src/app.d
import { interface KVNamespace<Key extends string = string>KVNamespace, interface DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined>DurableObjectNamespace } from '@cloudflare/workers-types';

declare global {
	namespace App {
		interface interface App.Platform

If your adapter provides platform-specific context via event.platform, you can specify it here.

Platform
{
App.Platform.env?: {
    YOUR_KV_NAMESPACE: KVNamespace;
    YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace;
} | undefined
env
?: {
type YOUR_KV_NAMESPACE: KVNamespace<string>YOUR_KV_NAMESPACE: interface KVNamespace<Key extends string = string>KVNamespace; type YOUR_DURABLE_OBJECT_NAMESPACE: DurableObjectNamespace<undefined>YOUR_DURABLE_OBJECT_NAMESPACE: interface DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined>DurableObjectNamespace; }; } } } export {};

Testing Locally

Cloudflare Workers specific values in the platform property are emulated during dev and preview modes. Local bindings are created based on your Wrangler configuration file and are used to populate platform.env during development and preview. Use the adapter config platformProxy option to change your preferences for the bindings.

For testing the build, you should use Wrangler version 3. Once you have built your site, run wrangler dev.

Troubleshooting

Node.js compatibility

If you would like to enable Node.js compatibility, you can add the nodejs_compat compatibility flag to your Wrangler configuration file:

wrangler
{
	"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 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 for more information.

Accessing the file system

You can’t use fs in Cloudflare Workers — you must prerender the routes in question.

Edit this page on GitHub