Cloudflare
Serve bundles from R2 behind a Cloudflare Worker.
The Cloudflare provider serves bundles from an R2 bucket through a Worker, using a KV namespace to record which version is deployed.
Provision the server
@wvb/remote-cloudflare-provider-pulumi provisions the Worker, R2 bucket, and KV namespace as a Pulumi component:
npm install @wvb/remote-cloudflare-provider-pulumiimport { WebviewBundleRemoteProvider } from '@wvb/remote-cloudflare-provider-pulumi';
const remote = new WebviewBundleRemoteProvider('wvb', {
accountId: '<cloudflare-account-id>',
});
export const bucketName = remote.bucketName;
export const kvNamespaceId = remote.kvNamespaceId;To write the Worker yourself, @wvb/remote-cloudflare-provider exports a Hono app. Bind an R2 bucket as BUCKET and a KV namespace as KV, then map them into the handler:
import { wvbRemote } from '@wvb/remote-cloudflare-provider';
const app = wvbRemote();
export default {
fetch(req: Request, env: { KV: KVNamespace; BUCKET: R2Bucket }) {
return app.fetch(req, { kv: env.KV, r2: env.BUCKET });
},
};Publish to it
@wvb/remote-cloudflare provides the uploader and deployer for your config:
npm install -D @wvb/remote-cloudflareimport { defineConfig } from '@wvb/config';
import { cloudflareRemote } from '@wvb/remote-cloudflare';
export default defineConfig({
remote: {
endpoint: 'https://updates.example.com',
...cloudflareRemote({
accountId: '<cloudflare-account-id>',
bucket: 'webview-bundle',
kvNamespaceId: '<kv-namespace-id>',
}),
},
});The uploader writes to R2 over the S3-compatible API, so pass R2 access keys through its s3ClientConfig.credentials; the deployer updates KV with a Cloudflare API token. See the Cloudflare client reference for the full config.
The Worker reads an R2 binding named BUCKET and a KV binding named KV. Match those names in
your wrangler.jsonc.