Build Configuration & Framework Presets
By the end of this module you will be able to configure Cloudflare Pages build settings for Docusaurus, set environment variables for different deployment environments, and troubleshoot common build configuration issues.
Build Pipeline Architecture
flowchart TD
PUSH["git push"] --> TRIGGER["Build Trigger\n(webhook from GitHub/GitLab)"]
TRIGGER --> CLONE["Clone Repository\nat commit SHA"]
CLONE --> CACHE["Restore Build Cache\n(node_modules)"]
CACHE --> INSTALL["Install Dependencies\nnpm ci"]
INSTALL --> BUILD["Run Build Command\nnpm run build"]
BUILD --> VALIDATE["Validate Output\n(check output directory)"]
VALIDATE --> UPLOAD["Upload to Edge\n(Cloudflare network)"]
UPLOAD --> ACTIVATE["Atomic Activation\n(zero downtime)"]
style TRIGGER fill:#f6821f,color:#fff,stroke:#e5711e
style BUILD fill:#2563eb,color:#fff,stroke:#1e40af
style ACTIVATE fill:#16a34a,color:#fff,stroke:#15803d
Docusaurus Configuration
Docusaurus is the primary use case documented here — the exact configuration for the author's tested workflow.
Build Settings
| Setting | Value |
|---|---|
| Build command | npm run build |
| Build output directory | build |
| Root directory | / (leave blank) |
| Node.js version | 20 (recommended) |
Environment Variables for Docusaurus
# Set in Cloudflare Pages → Settings → Environment Variables
# Node.js version (critical — must match your local dev)
NODE_VERSION=20
# Increase memory for large sites (many pages)
NODE_OPTIONS=--max-old-space-size=4096
# Optional: Docusaurus environment detection
NODE_ENV=production
# Optional: Algolia DocSearch
ALGOLIA_APP_ID=your-app-id
ALGOLIA_SEARCH_API_KEY=your-search-key
Cloudflare Pages defaults to Node.js 18 if NODE_VERSION is not set. Docusaurus 3.x requires Node.js ≥18.0. Set NODE_VERSION=20 explicitly for best compatibility.
docusaurus.config.js for Pages
// @ts-check
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'My Documentation',
tagline: 'Comprehensive guides',
// ✅ Set to your production domain (or pages.dev subdomain)
url: 'https://docs.yourdomain.com',
// ✅ Use '/' for root deployment (standard for Pages)
baseUrl: '/',
// ✅ Set to 'ignore' unless you want build to fail on broken links
onBrokenLinks: 'warn',
onBrokenMarkdownLinks: 'warn',
// ... rest of config
};
module.exports = config;
Framework Presets Reference
Cloudflare Pages supports auto-detection for these frameworks:
| Framework | Build Command | Output Dir | Notes |
|---|---|---|---|
| Docusaurus | npm run build | build | ✅ Auto-detected |
| Next.js | npx @cloudflare/next-on-pages | .vercel/output/static | Requires adapter |
| Astro | npm run build | dist | ✅ Auto-detected |
| Vite (React/Vue) | npm run build | dist | ✅ Auto-detected |
| Hugo | hugo | public | Requires HUGO_VERSION env var |
| Gatsby | gatsby build | public | ✅ Auto-detected |
| SvelteKit | npm run build | build | Requires adapter |
| Nuxt 3 | npm run generate | dist | Use static generation |
| MkDocs | mkdocs build | site | Requires Python setup |
| 11ty (Eleventy) | npx @11ty/eleventy | _site | ✅ Auto-detected |
Environment Variables — Complete Guide
Types of Variables
| Type | Use Case | Visibility in Logs |
|---|---|---|
| Plain text variable | Non-sensitive config (Node version, API URLs) | Visible |
| Encrypted secret | API keys, tokens, passwords | Hidden |
Set Variables in Dashboard
- Go to your Pages project → Settings → Environment Variables
- There are two environments: Production and Preview
- Click Add variable → enter name and value
- Toggle Encrypt for sensitive values
Set Variables via Wrangler
# Set a plain variable (use wrangler pages secret for secrets)
# Note: Wrangler 'pages secret put' works for both plain and encrypted
# Production environment
wrangler pages secret put NODE_VERSION \
--project-name my-docs \
--env production
# Prompt: Enter value: 20
# Preview environment
wrangler pages secret put NODE_VERSION \
--project-name my-docs \
--env preview
# Prompt: Enter value: 20
Set Variables via API
curl -X PATCH \
"https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/pages/projects/${CF_PROJECT}" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"deployment_configs": {
"production": {
"env_vars": {
"NODE_VERSION": { "value": "20" },
"NODE_OPTIONS": { "value": "--max-old-space-size=4096" }
}
},
"preview": {
"env_vars": {
"NODE_VERSION": { "value": "20" }
}
}
}
}' | jq .
Variable Inheritance
- Variables set for Preview apply to all preview deployments (non-production branches).
- Variables set for Production apply only to the production branch.
- Variables are not inherited between environments — set them separately.
Access Variables in Docusaurus Build
For variables used during the build (not runtime), use process.env:
const config = {
// Use env var with fallback
url: process.env.SITE_URL || 'https://my-docs.pages.dev',
themeConfig: {
algolia: {
appId: process.env.ALGOLIA_APP_ID,
apiKey: process.env.ALGOLIA_SEARCH_API_KEY,
indexName: 'my-docs',
},
},
};
Docusaurus is a static site generator — environment variables are consumed at build time only. They are baked into the output HTML/JS. They are NOT available at request time (unlike Pages Functions).
Build Cache
Cloudflare Pages caches node_modules between builds to speed up dependency installation.
Cache Invalidation
The cache is invalidated automatically when:
package-lock.jsonoryarn.lockchangesNODE_VERSIONenvironment variable changes- You manually clear the cache via dashboard
Force a Clean Build
# Option 1: Dashboard
# Workers & Pages → your-project → Deployments → Retry deployment
# Then tick "Clear build cache"
# Option 2: Temporarily change package-lock.json
# (add a space and remove it, then push)
# Option 3: Via CLI — delete and re-create the project
# (nuclear option — only for serious cache corruption)
Custom Build Environment
Specifying Node.js Version
# In Cloudflare Pages Settings → Environment Variables
NODE_VERSION = 20
You can also use a .nvmrc file in your repository root — Cloudflare Pages reads it automatically:
20
Or a package.json engines field:
{
"engines": {
"node": ">=20.0.0"
}
}
Python / Ruby / Go Builds
For non-Node.js static site generators:
| Language | Environment Variable | Example |
|---|---|---|
| Python | PYTHON_VERSION | 3.11 |
| Ruby | RUBY_VERSION | 3.2 |
| Hugo | HUGO_VERSION | 0.121.0 |
| Go | — | Installed by default |
Monorepo Configuration
If your Docusaurus site is in a subdirectory of a monorepo:
my-monorepo/
├── packages/
│ └── docs/ ← Docusaurus site here
│ ├── package.json
│ └── docusaurus.config.js
├── apps/
└── package.json ← Monorepo root
In Cloudflare Pages build settings:
| Setting | Value |
|---|---|
| Root directory | packages/docs |
| Build command | npm run build |
| Build output directory | build |
Build Hooks (Incoming Webhooks)
Build hooks let you trigger a Pages build from external systems without a Git push:
Create a Build Hook via API
curl -X POST \
"https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/pages/projects/${CF_PROJECT}/deploy_hooks" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "Trigger from CMS",
"branch": "main"
}' | jq '.result.url'
# Output:
# "https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/abc123..."
Trigger a Build via Hook
HOOK_URL="https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/abc123..."
curl -X POST "$HOOK_URL"
Build hooks are ideal for headless CMS setups — configure your CMS (Contentful, Sanity, etc.) to call the webhook when content is published, triggering an automatic Docusaurus rebuild.
List and Delete Hooks
# List
curl "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/pages/projects/${CF_PROJECT}/deploy_hooks" \
-H "Authorization: Bearer ${CF_API_TOKEN}" | jq .
# Delete
HOOK_ID="hook-id-123"
curl -X DELETE \
"https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/pages/projects/${CF_PROJECT}/deploy_hooks/${HOOK_ID}" \
-H "Authorization: Bearer ${CF_API_TOKEN}"
Build Configuration Reference
| Setting | Location | Notes |
|---|---|---|
| Build command | Dashboard / API | npm run build for Docusaurus |
| Output directory | Dashboard / API | build for Docusaurus |
| Root directory | Dashboard / API | Leave blank unless monorepo |
| Node version | NODE_VERSION env var or .nvmrc | Default: 18, use 20+ |
| Memory | NODE_OPTIONS env var | --max-old-space-size=4096 |
| Build timeout | Plan limit (20 min free) | Cannot be changed on free tier |
| Cache | Automatic (keyed on lockfile) | Clear in dashboard if needed |
Key Takeaways
- Docusaurus build settings: command
npm run build, outputbuild, Node 20+. - Set
NODE_VERSION=20as an environment variable to ensure correct runtime. - Use
NODE_OPTIONS=--max-old-space-size=4096for large sites with many pages. - Environment variables are build-time only for static sites — not runtime.
- Deploy hooks let external systems (CMS, cron jobs) trigger builds without Git.
- Monorepos: set Root directory to your Docusaurus package subdirectory.
What's Next
- Continue to Preview Deployments & Branch Control for advanced deployment workflows.