Deployment
Deploy your documentation to any static hosting provider and configure clean URLs.
Flame builds a fully static site — no server runtime is required. flame build (or bun run build / npm run build / deno task build) writes everything to .docu/dist/:
The docs/ directory is the prefix from meta.basePath — change it to /handbook and pages are written to .docu/dist/handbook/, set it to "" and they land at the dist root.
Pages are emitted as flat .html files, and internal links are generated with the .html suffix so navigation works on any static host that serves files by exact path — with zero configuration.
Whether the .html suffix stays visible in the browser address bar depends on your provider's clean URL support. Some providers strip the suffix automatically, others need a small config file, and a few cannot rewrite URLs at all.
Serving Under a Subpath
Two settings decide where the site answers, and they are independent:
A GitHub Pages project site serves the artifact under the repository name, so baseURL must include it:
That deploys pages to https://acme.github.io/handbook/docs/…. The pathname of baseURL is what root-absolute references — the 404 fallback's bundle assets and the search index records — are built from, so omitting the repository segment sends them to the origin root, where they 404. Relative references need nothing: pages and assets share the deployment root.
Do not repeat the docs prefix in baseURL — it is appended automatically when canonical and Open Graph URLs are built. See Base Path & Subpaths for root deployments, canonicalization, and verification steps.
Provider Overview
Column notes:
- Auto-deploy on push — "Native GitHub" means the provider has a built-in GitHub integration (e.g. Cloudflare Pages, Vercel, Netlify) that connects to your repo and auto-builds on every push. "GitHub Action" means you need a workflow file (providers supply one via their setup UI).
- Server — the underlying HTTP server that serves your static files. All providers serve
.docu/dist/directly — no app server required.
For providers with Native GitHub or GitHub Action support, deployment is fully automated: push to your default branch, and the site updates minutes later. No manual upload or CLI step needed after the initial setup.
Zero Configuration
These providers handle clean URLs automatically — deploy .docu/dist/ as-is.
Cloudflare Pages
Cloudflare Pages natively redirects /page.html → /page and /about/index.html → /about/. No config file needed.
Source: Cloudflare Pages — Serving Pages
AWS Amplify Hosting
Amplify automatically serves /about from /about.html when the file exists. It resolves .html extensions and trailing slashes based on the build output — no additional configuration required.
Source: AWS Amplify — Trailing slashes and clean URLs
Configuration Required
These providers support clean URLs, but you must enable them explicitly.
Vercel
When true, Vercel strips .html from all URLs and responds with a 308 redirect for /page.html → /page.
:::info title="DocuBook repository"
The vercel.json in the DocuBook repository already sets "cleanUrls": true — deployments of this
documentation site need no extra configuration.
:::
Source: Vercel — cleanUrls
:::info title="Last updated dates on Vercel"
Vercel uses a shallow git clone (--depth=1) by default, which prevents Flame from
reading the last modified date for each page via git log. Add the following environment
variable in your Vercel project dashboard (Settings → Environment Variables):
:::
Netlify
Alternatively, enable it in the UI: Project configuration → Build & deploy → Post processing → Pretty URLs.
Source: Netlify — Pretty URLs
Firebase Hosting
When true, Firebase drops .html from uploaded URLs and responds with a 301 redirect for requests that include the extension.
Source: Firebase — Full hosting configuration
Azure Static Web Apps
Azure SWA has no cleanUrls option, and route redirect values do not support wildcard captures — so per-route redirect rules cannot strip .html site-wide. Use the trailingSlash setting instead, which normalizes URLs globally:
With "never" (or "auto"), a request to /docs/page.html is permanently redirected (301) to /docs/page, and the .html file is served at the extensionless path. Place the config file at the root of the deployed output.
Source: Azure Static Web Apps — Configuration
Render
Render does not strip .html automatically. Add a rewrite rule in the Render Dashboard:
Render serves existing files first — the rule only applies when no file exists at the requested path, so it never shadows real assets. Note that Render has no redirect in the other direction: links within the site keep their .html suffix, and the rewrite ensures extensionless URLs resolve when visited directly.
Source: Render — Redirects and Rewrites
Heroku
Heroku has no native static hosting — use the heroku-community/static buildpack and add static.json to the repo root:
clean_urls: true configures nginx to serve /page from /page.html.
:::warning title="Deprecated buildpack"
Heroku has deprecated heroku-buildpack-static and no longer maintains it. It still works, but
Heroku recommends the nginx buildpack for new
projects.
:::
Source: Heroku — static buildpack
Limited Support
These platforms cannot rewrite URLs — the site still works, but the .html suffix stays visible.
GitHub Pages
GitHub Pages serves files at their exact path only: /docs/page.html works, /docs/page returns a 404. There is no official rewrite mechanism for static files.
Project sites are published under the repository name, so meta.baseURL has to name that path (https://<user>.github.io/<repo>) — see Serving Under a Subpath.
Flame ships a deploy helper — flame deploy (or bun run deploy / npm run deploy / deno task deploy) builds the site, adds a .nojekyll file, and generates a .github/workflows/deploy.yml workflow if one does not exist. The generated workflow automatically builds and deploys on every push to the default branch. The .html suffix remaining in the address bar is the only limitation — the site itself works perfectly.
Source: GitHub Pages documentation
AWS S3 + CloudFront
S3 static website hosting does not strip .html extensions. Clean URLs require a viewer-request handler on the CloudFront distribution — a CloudFront Function or Lambda@Edge — that appends .html to extensionless request URIs before they reach S3. This requires additional AWS infrastructure beyond a basic static deploy.
Source: Amazon S3 — Hosting a static website
Docker Deployment
Flame supports Docker deployment for any platform that runs Docker images — Coolify, Fly.io, Railway, VPS, or container hosting.
Generates:
Dockerfile— multi-stage build tailored to the project's package managernginx.conf— security headers, cache tiers, clean URLs, and the generated404.html. The content-assets cache block followsmeta.basePath; at a root deployment ("basePath": "") it is omitted because both asset trees would claim/assets/..dockerignore— optimized for build speed
The builder stage follows the detected package manager. Bun projects build inside the published ghcr.io/docubook/flame builder image pinned to the installed @docubook/flame version — the CLI is already global there, so no dependency install step is needed. npm, pnpm, and yarn projects build on node:22-alpine and install their locked dependencies (npm ci, pnpm install --frozen-lockfile, yarn install --frozen-lockfile) before running the project's build script, so packages your docs import are always available. Detection is lockfile-first; a project without a lockfile falls back to the package manager that invoked the CLI and runs a plain install (npm install, pnpm install, …). Upgrade @docubook/flame, then rerun flame deploy --docker when you want a newer builder. The final output is a nginx container serving flat .html files with clean URLs.
Build locally
Prerequisites:
- Docker installed on your machine
flameCLI — run viabunx flame,npx flame, or install globally withbun install -g @docubook/flame
Auto-build on push (with CI)
Also generates .github/workflows/deploy-docker.yml — a CI workflow that automatically builds and pushes the Docker image to GitHub Container Registry on every git push. The workflow structure is generated by flame deploy --docker --ci itself; see the source at packages/flame/.docu/node/deploy.shared.ts → generateDockerWorkflowYml().
The image is pushed to ghcr.io/your-org/your-repo:latest. Your hosting platform (Coolify, Fly.io, etc.) can then pull the latest image.
Platform guide
See the Provider Overview table above for each platform's clean URL and configuration details.
Last updated Sep 24, 2026