Cloudflare Pages
The cloudflarePages adapter uses the Direct Upload API. Create the project once in the Cloudflare dashboard (Workers & Pages > Create > Pages > Direct Upload), then:
import { defineConfig } from "@kilim-dev/core";
import { cloudflarePages } from "@kilim-dev/core/adapters";
export default defineConfig({
url: "https://www.example.com",
deploy: cloudflarePages({
accountId: "0123456789abcdef0123456789abcdef",
project: "my-blog",
// Pull requests deploy as previews; other runs go to the production branch.
branch: process.env.GITHUB_HEAD_REF,
}),
});- The API token comes only from the
CLOUDFLARE_API_TOKENenvironment variable; it needs the Cloudflare Pages: Edit permission. Never put it in the config. branchdefaults to the project's production branch. Any other branch is a preview deployment; an empty string counts as not set.messageis shown with the deployment in the dashboard (defaultDeploy <time>).- Every deployment includes
_kilim/deploy.json, the list of its files and their hashes. The nextkilim deployreads it to show what is added, changed and removed. When a deployment has none (e.g. one made with another tool, or behind Cloudflare Access), Kilim compares by content only and cannot list removed files. _headersand_redirectsfrom the build are sent with the deployment, so CSP headers and redirects work. Files are uploaded only when Cloudflare does not have them yet; files over 25 MiB are rejected.
# .github/workflows/cloudflare.yml
name: Cloudflare Pages
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
cache: npm
- run: npm ci
- run: npx kilim deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}