Setup
Connect deploykit to Cloudflare Pages.
Install
Follow the installation guide to install the alpha packages, then configure the provider below.
Add credentials
In the Cloudflare dashboard, create an API token with the Cloudflare Pages: Edit permission, and copy your account id.
CLOUDFLARE_API_TOKEN=...
CLOUDFLARE_ACCOUNT_ID=...Create the client
import { Layer } from "effect"
import { NodeFileSystem } from "@effect/platform-node"
import * as Cloudflare from "@deploykit/cloudflare"
// Reads CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID from the environment.
export const DeploykitLive = Cloudflare.layerConfig().pipe(Layer.provide(NodeFileSystem.layer))To pass options, use layer instead:
export const DeploykitLive = Cloudflare.layer({
apiToken,
accountId,
previewBranch: "preview"
}).pipe(Layer.provide(NodeFileSystem.layer))Client options
| Option | Default | What it does |
|---|---|---|
apiToken | required | Cloudflare API token |
accountId | required | Account that owns the projects |
previewBranch | none | Enables preview deployments |
retry | { attempts: 4 } | Retries for reads and uploads |
timeoutMs | 30000 | Time limit per HTTP operation, including retries |
fetch | global fetch | Custom HTTP transport |
memoryBudgetBytes, stagingBudgetBytes, maxFileBytes | see Limits | Shared memory and disk caps |
onEvent | none | Telemetry callback (Promise API). See Telemetry |
What to deploy
The site's files at the root of the artifact, exactly as they should be served. This is what your
framework puts in dist/ or build/:
index.html
about/index.html
assets/app.js
_worker.js (optional, see Workers)await deploykit.deployDirectory(appId, "./dist")To run server code, add a _worker.js.
Pages' _headers, _redirects and _routes.json files aren't applied yet: they're uploaded as
ordinary files. Set headers and redirects from your worker instead.
Deploy options
Pages supports the core options only. activation: "deferred",
operationId and meta fail with UnsupportedError before anything is uploaded.
Preview deployments
Pages decides production versus preview by branch name. Set previewBranch on the client, then
deploy with target: "preview":
const PreviewLive = Cloudflare.layer({
apiToken,
accountId,
previewBranch: "preview"
})
const preview = Effect.gen(function* () {
const deploykit = yield* Deploykit.Deploykit
return yield* deploykit.deployDirectory(appId, "./dist", {
target: "preview"
})
})The branch must differ from the project's production branch. Without previewBranch,
target: "preview" is rejected, and capabilities.previewDeployments is false.
Limits
| Limit | Value |
|---|---|
| Static file | 25 MiB (Cloudflare's limit) |
_worker.js | 8 MiB |
| Uploads at once | 4 per deploy |
Files over 25 MiB fail with TransferLimitError before upload, whatever your budgets allow.
Not supported
| Feature | What to do instead |
|---|---|
| Deferred activation | Every production deploy goes live when ready. Use a preview to check first |
| Recovering a lost response | Check the project's deployments in Cloudflare before retrying |
| Access control | Use Cloudflare Access on the project's domain |
A new project's first URL
A new project's *.pages.dev address can take 30 to 60 seconds to start resolving after its first
deploy. Give waitUntilServing a generous timeoutMs, such as 120 seconds.
Separate coordinator and worker
@deploykit/cloudflare/control has no upload code and can be bundled for the browser or an edge
runtime:
import { makeCloudflareClient, makeCloudflareControl } from "@deploykit/cloudflare/control"
const control = makeCloudflareControl(makeCloudflareClient({ apiToken, accountId }))
// control.createApp, getDeployment, ... all return EffectsLast updated on