Cloudflare Plugin
Install
pnpm add -D @theholocron/holocron-plugin-cloudflareCapabilities
| Capability | Token |
|---|---|
dns | HOLOCRON_CLOUDFLARE_TOKEN (cloudflare) |
deployment | HOLOCRON_CLOUDFLARE_TOKEN (cloudflare) + CLOUDFLARE_ACCOUNT_ID |
Config
Section titled “Config”providers: { dns: "cloudflare",}With Cloudflare Pages deployments:
providers: { dns: "cloudflare", deployment: "cloudflare",}The deployment capability is enabled automatically when CLOUDFLARE_ACCOUNT_ID is set in the environment (or passed as accountId in plugin options).
Options
Section titled “Options”| Option | Required | Description |
|---|---|---|
accountId |
No | Cloudflare account ID. Falls back to CLOUDFLARE_ACCOUNT_ID env var. Required for deployment capability. |
Authentication
Section titled “Authentication”- Go to dash.cloudflare.com/profile/api-tokens
- Click Create Token → Custom token
- Set permissions:
- Zone → Zone → Read, Zone → DNS → Edit (required for
dns) - Cloudflare Pages → Edit (also required for
deployment)
- Zone → Zone → Read, Zone → DNS → Edit (required for
- Optionally scope to specific zones, then click Continue to summary → Create Token
- Copy the token (shown once)
holocron auth set cloudflare <TOKEN>Or via env var:
export HOLOCRON_CLOUDFLARE_TOKEN=<TOKEN># Also recognized:export CLOUDFLARE_API_TOKEN=<TOKEN>For Pages deployments, also set the account ID:
export CLOUDFLARE_ACCOUNT_ID=<ACCOUNT_ID>What dns provides
Section titled “What dns provides”listRecords(domain)— list all DNS records for the zone (zone resolved automatically from domain)upsertRecord(domain, record)— create or update a DNS record by type and namedeleteRecord(domain, id)— delete a DNS record by id
Zone resolution walks from the full domain up to the apex automatically — e.g. api.staging.example.com tries api.staging.example.com, then staging.example.com, then example.com.
What deployment provides
Section titled “What deployment provides”Manages Cloudflare Pages projects. Used by holocron setup to provision per-PR preview deployments.
ensureProject(input)— create the Pages project if it does not exist; return the existing project otherwiseensureCustomDomain(projectId, hostname)— attach a custom domain to the project; idempotentlistDeployments(projectId)— list recent deploymentstriggerDeployment(projectId)— trigger a new deployment from the production branch
Preview deployment flow
Section titled “Preview deployment flow”Add preview: true to the deploy entry in holocron.config.ts:
org: "myorg",domain: "myorg.dev",workflows: [ { name: "deploy", with: { docs: true, preview: true } }]preview: true derives defaults from your config:
project=<org>-previewdomain=preview.<domain>(used for DNS provisioning only)
Running holocron setup provisions the Pages project, apex custom domain, and DNS records. The deploy.yml thin caller generated by holocron sync routes push events to GitHub Pages and pull_request events to Cloudflare Pages. Preview deployments are automatically deleted when the PR is closed.
Preview URLs
Section titled “Preview URLs”Every PR gets a stable branch URL:
https://<repo>-pr-<n>.<project>.pages.dev/<base-path>/For example, PR #42 on the holocron repo with project theholocron-preview:
https://holocron-pr-42.theholocron-preview.pages.dev/holocron/This URL is posted as a PR comment and shown in the GitHub Deployments sidebar. It stays stable across re-deployments of the same PR number.
Debugging in the Cloudflare dashboard
Section titled “Debugging in the Cloudflare dashboard”Go to Workers & Pages → <project-name> to see:
- Deployments tab — all branch deployments with hash URL, branch name, commit, and timestamp. Click any deployment for its build log.
- Custom domains tab — verify the apex domain is active.
- Settings → Builds & deployments — do not connect a Git repository; deployments are driven by GitHub Actions via the API.
If a preview deploy fails, check the Deployments tab → click the failed deployment → View build log.
Example
Section titled “Example”import { createPlugin } from "@theholocron/holocron-plugin-cloudflare";
const plugin = createPlugin({ token: process.env.HOLOCRON_CLOUDFLARE_TOKEN });const dns = plugin.capabilities.dns();
await dns.upsertRecord("example.com", { type: "TXT", name: "_acme-challenge.example.com", content: "verification-token", ttl: 60,});