This file helps AI agents understand the structure, tooling, and conventions of the cloudflare-docs repository so they can make correct, buildable changes.
This is the source for developers.cloudflare.com. It is an Astro site using the Starlight documentation framework. Content is authored in MDX (Markdown + JSX). The site is deployed as a Cloudflare Worker.
- Node.js: 24.x
- Package manager: pnpm (use
pnpm install --frozen-lockfileto install) - Primary branch:
production(notmain)
cloudflare-docs/
├── src/
│ ├── content/
│ │ ├── docs/ # 5,400+ MDX pages — the user-facing documentation
│ │ ├── partials/ # 1,200+ reusable MDX snippets (by product)
│ │ ├── changelog/ # Product changelogs (by product subdirectory)
│ │ ├── glossary/ # Glossary term definitions (YAML)
│ │ ├── products/ # Product metadata (YAML, 135 files)
│ │ └── ... # Other data collections (plans, fields, models, etc.)
│ ├── components/ # Custom Astro + React components
│ │ ├── index.ts # Central re-export barrel — all MDX imports come from here
│ │ └── overrides/ # Starlight component overrides (Banner, Footer, Head, etc.)
│ ├── schemas/ # Zod schemas for all content collections
│ ├── plugins/ # Remark, Rehype, Starlight, and Expressive Code plugins
│ ├── icons/ # Product SVG icons (~110)
│ ├── assets/ # Processed images (optimized by Astro)
│ ├── styles/ # CSS (Tailwind 4)
│ ├── pages/ # Dynamic route pages (changelog, glossary, search)
│ └── util/ # Shared utility functions
├── public/ # Static files served as-is (images, redirects, robots.txt)
├── worker/ # Cloudflare Worker for serving the site
├── bin/ # Build scripts and CI helpers
│ └── fetch-skills.ts # Downloads skills.tar.gz from middlecache, extracts to skills/
├── skills/ # Agent Skills served at /.well-known/skills/ — GENERATED, do not edit
│ # Fetched from https://middlecache.ced.cloudflare.com/v1/cloudflare-skills/skills.tar.gz
│ # by bin/fetch-skills.ts, which runs automatically via prebuild/predev hooks.
│ # skills/ is in .gitignore and is NOT committed to the repository.
├── astro.config.ts # Astro + Starlight configuration
├── ec.config.mjs # Expressive Code (syntax highlighting) configuration
├── package.json
└── tsconfig.json
- Docs pages:
src/content/docs/{product}/ - Partials (reusable snippets):
src/content/partials/{product}/ - Images:
src/assets/images/{product}/ - Changelogs:
src/content/changelog/{product}/
Every folder must have an index.mdx. Filenames must be lowercase with dashes between words.
Only .mdx, .json, .yml, .yaml, .txt files are allowed. The CI will reject anything else. Images must go in src/assets/images/, not in src/content/.
All docs pages require frontmatter. Key fields:
---
title: Page Title # Required
description: SEO meta description # Required when pcx_content_type is set
pcx_content_type: how-to # Page type (see below)
sidebar:
order: 1 # Sort order in sidebar
label: Custom Label # Override sidebar text
products: # References to src/content/products/ entries
- workers
difficulty: Beginner # For tutorials: Beginner | Intermediate | Advanced
reviewed: 2025-01-15 # YYYY-MM-DD of last content review
---Valid pcx_content_type values: changelog, concept, configuration, design-guide, example, faq, get-started, how-to, integration-guide, implementation-guide, learning-unit, navigation, overview, reference, reference-architecture, reference-architecture-diagram, release-notes, solution-guide, troubleshooting, tutorial, video.
For MDX syntax, links, code blocks, formatting, and writing style, see .agents/references/style-guide.md. That file is the canonical agent reference — distilled from the full style guide at src/content/docs/style-guide/.
Components are imported from ~/components in MDX files. Imports must appear after the frontmatter block — forgetting the import is a common mistake.
For full component documentation including props, examples, and mandatory usage rules, see .agents/references/components.md.
CI note:
pnpm run buildwill time out in CI environments (GitHub Actions, etc. whereCI=true). When running in CI, usepnpm run checkand linters only — do not run a full build. The full build is only practical in local development environments.
pnpm run check # Type-check (validates frontmatter schemas + Astro types)
pnpm run build # Full build (validates MDX parsing, image paths, internal links) — LOCAL ONLY, skip in CIpnpm run check # Type-check (Astro + Worker)
pnpm run lint # ESLint
pnpm run format:core:check # Prettier formatting check
pnpm run test # Vitest (Workers, Node, and Astro suites)Use this reduced set when running as a GitHub Action or in any CI environment:
pnpm run check # Type-check (validates frontmatter schemas + Astro types)
pnpm run lint # ESLint
pnpm run format:core:check # Prettier formatting checkpnpm run check # Astro + Worker type checking
pnpm run lint # ESLint
pnpm run format:core:check # Prettier formatting check
pnpm run build # Full build with link checking (set RUN_LINK_CHECK=true)
pnpm run test # All test suites
pnpm exec tsm bin/validate-redirects.ts # Only if public/__redirects was modifiedAfter editing any .ts, .tsx, .js, .mjs, or .css file, run:
pnpm run format # Auto-fix code + data files
pnpm run format:content # Auto-fix MDX/MD/Astro filesAlways format edited files before committing — CI runs pnpm run format:core:check and will fail if formatting is off.
pnpm run sync # Regenerate Astro content collection typesThe CI workflow (.github/workflows/ci.yml) runs on PRs to production and checks in order:
- File extension validation (only allowed types in
src/content/) pnpm run check(Astro + Worker type checking)- ESLint (reported inline on PR via reviewdog)
pnpm run format:core:check(Prettier formatting)pnpm run buildwithRUN_LINK_CHECK=true(full build + internal link validation)- Redirect validation (
bin/validate-redirects.ts) pnpm run test(all Vitest suites)
A separate Semgrep workflow checks style guide compliance (dates, "coming soon" phrases) and produces warnings.
- Unescaped
{,},<,>in MDX prose — the #1 build failure. Wrap in backticks or escape. - Forgetting component imports —
<Details>,<Tabs>, etc. must be imported from~/components. - Unsupported code block languages — use
txtfor generic output, notoutputorenv. - Capitalized language names — use
jsonnotJSON,javascriptnotJavaScript. - Full URLs for internal links — use
/workers/nothttps://developers.cloudflare.com/workers/. - Relative file links —
./pageis not supported. Use absolute paths from root. - Wrong image location — images go in
src/assets/images/, never insrc/content/. - Skipping heading levels — H2 then H4 without H3 will violate style guide rules.
$prefix in terminal commands — the copy button copies verbatim, including the$.- Invalid changelog product folders — the product directory must exist in
src/content/products/. - Redirect issues — source URLs in
public/__redirectsmust end in/(or*,.xml,.json,.html). No fragments in source URLs. No infinite loops. - Hand-crafted directory entry IDs — never manually write
idvalues insrc/content/directory/files. Always runnode tools/directory-entry-ids --fixto generate them.
The site defines 20 content collections in src/content.config.ts with schemas in src/schemas/. The major ones:
| Collection | Location | Description |
|---|---|---|
docs |
src/content/docs/ |
Main documentation pages (MDX) |
partials |
src/content/partials/ |
Reusable content snippets (MDX) |
changelog |
src/content/changelog/ |
Product changelogs (MDX) |
glossary |
src/content/glossary/ |
Glossary terms (YAML) |
products |
src/content/products/ |
Product metadata (YAML) |
plans |
src/content/plans/ |
Plan/pricing data (YAML) |
workers-ai-models |
src/content/workers-ai-models/ |
AI model definitions (JSON) |
directory |
src/content/directory/ |
Product/feature directory entries (YAML) |
fields |
src/content/fields/ |
Ruleset engine field definitions (YAML) |
learning-paths |
src/content/learning-paths/ |
Learning path definitions (JSON) |
Every file in src/content/directory/ must have a unique id field on the very first line. This is enforced by Semgrep rules in CI (.semgrep/directory-entry-validation.yaml).
Rules:
- The
idmust be exactly 6 characters long. - Characters are drawn from a reduced-confusion set:
abcdefghijkmnopqrstuvwxyzACDEFGHJKLMNPQRTUVWXY34679. This deliberately omits visually ambiguous characters (l/1/I,O/0,B/8,S/5,Z/2). - IDs are randomly generated — they must not contain human names or be hand-crafted.
- The
idis a stable identifier that stays with the YAML file even when thenameor filename changes. Never modify an existingidunless fixing a validation error. - Files must use the
.yamlextension, not.yml.
Generating IDs:
Use the tools/directory-entry-ids script to generate and validate IDs:
node tools/directory-entry-ids # Check all files, report errors
node tools/directory-entry-ids --fix # Auto-fix missing, malformed, or duplicate IDsDo not manually write id values. Always use the script to generate them.
Tests use Vitest with three workspace projects (vitest.workspace.ts):
| Suite | File pattern | Runtime |
|---|---|---|
| Workers | *.worker.test.ts |
@cloudflare/vitest-pool-workers |
| Node | *.node.test.ts |
Node.js |
| Astro | *.astro.test.ts |
Astro Vite config |
Run all tests: pnpm run test
New web components in this codebase should use the cfdocs- prefix for custom element names (e.g., <cfdocs-sheet>, <cfdocs-explain-code>). This establishes a consistent naming pattern going forward.
- Custom element names: Use kebab-case with
cfdocs-prefix (e.g.,cfdocs-sheet) - Class names: Use PascalCase with
Elementsuffix (e.g.,SheetElement,ExplainCodeElement) - File locations: Place components in
src/components/{component-name}/directories
Existing components (warp-download, stream-player, rule-id, check-box, r2-local-uploads-diagram, animated-workflow-diagram, autoconfig-diagram) are exempt from the cfdocs- prefix requirement and do not need to be renamed.
Repo-specific skills live in .agents/skills/. Each skill provides specialized instructions for a particular task. Load a skill when the task matches its description.
| Skill | When to use |
|---|---|
changelog |
Creating, editing, or reviewing changelog entries |
code-review |
Reviewing Workers/platform code for type correctness and API usage |
dependabot-review |
Analyzing a Dependabot PR for impact on this repo |
docs-review |
Reviewing documentation PRs for style, structure, and correctness |
eli5 |
Simplifying technical documentation for broader audiences |
pr |
Creating or updating GitHub pull requests |
Shared reference files in .agents/references/:
| File | Contents |
|---|---|
style-guide.md |
Canonical writing and formatting rules for all content work |
components.md |
Full MDX component catalog with props and usage examples |
procedures.md |
Rules for writing step-by-step procedural instructions |
- Format:
[Product] descriptionortype: description - Examples:
[Workers] Fix broken link in get-started,docs: clarify rate limiting behavior,fix: correct TypeScript example - Common prefixes:
docs:,fix:,chore:,[Product]