Skip to main content

Build Configuration & Framework Presets

Learning Focus

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

SettingValue
Build commandnpm run build
Build output directorybuild
Root directory/ (leave blank)
Node.js version20 (recommended)

Environment Variables for Docusaurus

Recommended environment variables
# 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
Node.js Version

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

docusaurus.config.js — Pages-optimized
// @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:

FrameworkBuild CommandOutput DirNotes
Docusaurusnpm run buildbuild✅ Auto-detected
Next.jsnpx @cloudflare/next-on-pages.vercel/output/staticRequires adapter
Astronpm run builddist✅ Auto-detected
Vite (React/Vue)npm run builddist✅ Auto-detected
HugohugopublicRequires HUGO_VERSION env var
Gatsbygatsby buildpublic✅ Auto-detected
SvelteKitnpm run buildbuildRequires adapter
Nuxt 3npm run generatedistUse static generation
MkDocsmkdocs buildsiteRequires Python setup
11ty (Eleventy)npx @11ty/eleventy_site✅ Auto-detected

Environment Variables — Complete Guide

Types of Variables

TypeUse CaseVisibility in Logs
Plain text variableNon-sensitive config (Node version, API URLs)Visible
Encrypted secretAPI keys, tokens, passwordsHidden

Set Variables in Dashboard

  1. Go to your Pages project → SettingsEnvironment Variables
  2. There are two environments: Production and Preview
  3. Click Add variable → enter name and value
  4. Toggle Encrypt for sensitive values

Set Variables via Wrangler

Set environment variables via Wrangler CLI
# 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

PATCH project config with environment variables
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:

docusaurus.config.js — reading env vars
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',
},
},
};
Build-time vs Runtime Variables

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.json or yarn.lock changes
  • NODE_VERSION environment variable changes
  • You manually clear the cache via dashboard

Force a Clean Build

Trigger a clean build manually
# 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

Environment variable method (recommended)
# 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:

.nvmrc
20

Or a package.json engines field:

package.json
{
"engines": {
"node": ">=20.0.0"
}
}

Python / Ruby / Go Builds

For non-Node.js static site generators:

LanguageEnvironment VariableExample
PythonPYTHON_VERSION3.11
RubyRUBY_VERSION3.2
HugoHUGO_VERSION0.121.0
GoInstalled 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:

SettingValue
Root directorypackages/docs
Build commandnpm run build
Build output directorybuild

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

POST /pages/projects/{name}/deploy_hooks
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

POST to the deploy hook URL
HOOK_URL="https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/abc123..."

curl -X POST "$HOOK_URL"
CMS Integration

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

Manage deploy 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

SettingLocationNotes
Build commandDashboard / APInpm run build for Docusaurus
Output directoryDashboard / APIbuild for Docusaurus
Root directoryDashboard / APILeave blank unless monorepo
Node versionNODE_VERSION env var or .nvmrcDefault: 18, use 20+
MemoryNODE_OPTIONS env var--max-old-space-size=4096
Build timeoutPlan limit (20 min free)Cannot be changed on free tier
CacheAutomatic (keyed on lockfile)Clear in dashboard if needed

Key Takeaways

  • Docusaurus build settings: command npm run build, output build, Node 20+.
  • Set NODE_VERSION=20 as an environment variable to ensure correct runtime.
  • Use NODE_OPTIONS=--max-old-space-size=4096 for 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