Publish to Cloudflare

Publish a static PathMX build as a Cloudflare Worker with Static Assets. Supported Plugin server slices can run alongside the exported pages.

Prepare the site and account

Start with the static export walkthrough in an initialized project. You need a Cloudflare account with permission to deploy Workers. For the custom-domain example below, use a domain in a zone managed by that account and replace every docs.example.com with your chosen hostname.

Authorize Wrangler from a local terminal, then confirm the selected account:

bunx wrangler@4.125.0 login
bunx wrangler@4.125.0 whoami

This is the Wrangler version used by the installed adapter. Login opens the browser's OAuth flow; whoami identifies the account. For headless use, provide CLOUDFLARE_API_TOKEN through your CI secret environment and configure accountId. See Wrangler authentication. Keep credentials out of Plugin files and version control.

Install

bun add @pathmx/cloudflare@beta

Configure the publication in a repository Plugin:

// plugins/cloudflare.plugin.ts
import { CloudflarePlugin } from "@pathmx/cloudflare"

export default CloudflarePlugin({
  worker: "my-pathmx-site",
  origin: "https://docs.example.com",
  domain: "docs.example.com",
})

Set accountId when local Cloudflare credentials can access more than one account. Use basePath when PathMX should live below an origin prefix such as /course-guide.

Custom Domains are the default. To attach an exact Worker route in an existing zone instead:

export default CloudflarePlugin({
  worker: "my-pathmx-site",
  origin: "https://docs.example.com",
  domain: "docs.example.com",
  routing: { type: "route", zone: "example.com" },
})

Publish

Build the local managed stage without contacting the deployment service:

bun run pmx cloudflare publish

Rebuild the local managed stage and ask Wrangler to validate it without deploying:

bun run pmx cloudflare publish --dry-run

The stage lives at .pathmx/publish/cloudflare/, with site/, routing data, Wrangler configuration, and a receipt. The commands print Staged N routes… or Validated N routes…. Dry-run does write the local stage; it does not change the deployed Worker.

Deploy and verify

Deploy after validation succeeds:

bun run pmx cloudflare publish --deploy

The adapter runs Wrangler's account check before deployment. A successful command prints Deployed N routes…. Open your configured HTTPS origin, follow a deep page link, reload it, and fetch its .md alternate. Confirm the content and assets match the staged site rather than treating a successful upload as page acceptance.

If authentication fails, run whoami again and log in or correct the CI token's account/permissions. If the domain cannot be attached, verify its zone and routing choice. The local stage remains available for inspection; rerun validation after correcting configuration. This static publication does not provision a writable PathMX account server.

Add Analytics to static pages

Install and enable the ordinary Analytics Plugin:

bun run pmx plugins add analytics

Then select its server slice in the existing Cloudflare Plugin:

import { CloudflarePlugin } from "@pathmx/cloudflare"

export default CloudflarePlugin({
  worker: "my-pathmx-site",
  origin: "https://docs.example.com",
  domain: "docs.example.com",
  servers: ["analytics"],
})

publish --dry-run validates the static pages, receiver bundle, and SQLite-backed Durable Object binding. publish --deploy creates the binding and applies the host migration. Each selected Plugin owns one named database instance, so a redeployment retains its observations. The adapter rejects uninstalled Plugins, Plugins without a publishServer hook, duplicate IDs, and unsupported mount paths. Published servers currently require an origin-root deployment (basePath omitted). Keep the server list and its order stable after first deployment; changing Durable Object classes requires an explicit Cloudflare migration plan. Never delete a namespace as part of a routine deployment or rollback.

For private CLI reports and exports, generate a random secret of at least 32 characters and install it using Wrangler's private input prompt:

bunx wrangler@4.125.0 secret put PATHMX_INSPECT_TOKEN --config .pathmx/publish/cloudflare/wrangler.jsonc

Supply that same secret as PATHMX_INSPECT_TOKEN when using the Analytics remote commands. It grants report/export access, not a public statistics API or arbitrary SQL. Missing reporting credentials fail closed without disabling page collection. Missing storage bindings or unavailable storage return 503 on the collector while static pages remain independently available.

SQLite state and secrets belong to Cloudflare, not the managed publication stage. Preserve the namespace when changing builds, and keep a successful Analytics export plus recovery bookmark before administrative recovery. For local Wrangler checks, place --persist-to storage outside .pathmx/publish/cloudflare/; staging replaces that whole generated directory.