This document provides comprehensive guidance for developers working on the CircleCI docs site.
- Development Environment Setup
- Development Workflow
- Content Authoring
- UI Customization
- Advanced Development Tasks
- Testing
- Common Issues and Solutions
- Node.js: v22 or later
- npm: v8 or later
- Git: Latest version recommended
-
Clone the repository:
git clone https://github.com/circleci/circleci-docs.git cd circleci-docs -
Install dependencies:
npm ci
This uses the
package-lock.jsonto ensure consistent installations. -
Environment variables: The project uses
dotenvxto manage environment variables. Create a.envfile in the project root with any necessary environment variables. (a .env.copy is provided)
For optimal developer experience, configure your editor with:
- AsciiDoc Extension: For editing
.adocfiles - ESLint: For JavaScript linting
- Prettier: For code formatting
Run the development server to preview changes locally:
npm run start:devThis command:
- Builds the UI bundle if necessary
- Starts a local server with live reload
- Watches for changes and rebuilds automatically
The site will be available at http://localhost:3000 by default.
-
Start development server:
npm run start:dev
-
Preview UI changes:
npm run preview:ui
This focuses on UI development with faster rebuilds.
-
Build UI bundle only:
npm run build:ui
-
Build complete site:
npm run build:docs
The site includes a markdown export feature that generates downloadable .md versions of all documentation pages. This feature is optimized for different environments:
- Local development (default): Markdown generation is disabled for faster rebuilds
- CI/production: Markdown generation is enabled automatically when
CI=trueis set - Manual override: Set
ENABLE_MARKDOWN_EXPORT=trueto enable or disable explicitly
To preview markdown export locally:
ENABLE_MARKDOWN_EXPORT=true npm run start:devTo build without markdown (faster local builds):
npm run build:docsNote: Generating markdown files processes all 563+ pages and adds significant time to each rebuild. Keep it disabled during active development and enable only when you need to test the download functionality.
main- Production-ready code- Feature branches - Named according to the feature being developed
Documentation is organized as Antora components:
docs/
├── component-name/
│ ├── antora.yml # Component configuration
│ └── modules/
│ ├── ROOT/ # Default module
│ │ ├── nav.adoc # Navigation
│ │ ├── pages/ # Content pages
│ │ └── ...
-
Create a new page: Add an AsciiDoc file in the appropriate
pages/directory.Example (
docs/guides/modules/getting-started/pages/new-feature.adoc):= New Feature Guide :description: How to use the new feature :page-toclevels: 3 == Introduction This guide explains how to use the new feature. == Steps 1. First step 2. Second step
-
Update navigation: Add an entry to the appropriate
nav.adocfile.Example:
* xref:index.adoc[Getting Started] ** xref:installation.adoc[Installation] ** xref:new-feature.adoc[New Feature Guide]
-
Add images and attachments: Place images in the
assets/images/directory of the module.Reference them using:
image::image-name.png[Alt text]
- Use headings (
=,==,===) for document structure - Include a document title and description
- Use AsciiDoc features like:
- Lists (
*for bullets,.for numbered) - Code blocks (indented with 4 spaces)
- Admonitions (
NOTE:,TIP:,IMPORTANT:,WARNING:,CAUTION:) - Tables
- Cross-references (
xref:)
- Lists (
The documentation supports tabbed content using the @asciidoctor/tabs extension:
[tabs]
====
Tab A::
+
--
Content for Tab A
--
Tab B::
+
--
Content for Tab B
--
====The UI project is located in the ui/ directory:
ui/
├── src/
│ ├── css/ # CSS styles
│ ├── helpers/ # Handlebars helpers
│ ├── img/ # Images
│ ├── js/ # JavaScript
│ ├── layouts/ # Page layouts
│ └── partials/ # Reusable template parts
├── gulpfile.js # UI build configuration
├── package.json # UI dependencies
└── tailwind.config.js # Tailwind CSS configuration
-
Modify UI files: Edit files in the
ui/src/directory. -
Build UI bundle:
npm run build:ui
-
Preview changes:
npm run preview:ui
The UI uses Tailwind CSS for styling:
-
Add or modify styles: Edit files in
ui/src/css/ -
Customize Tailwind: Modify
ui/tailwind.config.js -
Add custom components: Create new CSS files in
ui/src/css/and import them in the main CSS file
-
Add or modify scripts: Edit files in
ui/src/js/ -
Bundle structure: The main JavaScript bundle is
ui/src/js/site.js -
Add new features: Create new JavaScript files and import them in the main bundle
-
Create component directory:
mkdir -p docs/new-component/modules/ROOT/{pages,partials,examples,attachments} -
Create component configuration: Create
docs/new-component/antora.yml:name: new-component title: New Component version: ~ nav: - modules/ROOT/nav.adoc
-
Create navigation file: Create
docs/new-component/modules/ROOT/nav.adoc:* xref:index.adoc[Introduction] -
Create index page: Create
docs/new-component/modules/ROOT/pages/index.adoc -
Add to Antora playbook: Add an entry to
antora-playbook.yml:content: sources: # existing entries... - url: . start_path: docs/new-component
To create a custom extension:
-
Create extension file: Create a file in the
extensions/directory -
Implement the extension:
module.exports.register = function (registry, context) { // Extension code here }
-
Register in Antora playbook: Add to
antora-playbook.yml:asciidoc: extensions: - ./extensions/your-extension.js
The project includes several custom extensions:
page-metadata-extension.js: Adds metadata to pages (reading time, last updated, etc.)- Registered in:
antora-playbook.ymland command line
- Registered in:
export-content-extension.js: Exports content for search indexing- Registered in: command line only
markdown-export-extension.js: Generates downloadable markdown versions of all pages- Converts HTML to markdown using Turndown
- Preserves code blocks with syntax highlighting
- Converts relative links to absolute URLs
- Registered in: command line only (conditionally based on environment)
- Enabled automatically in CI, disabled in local development by default
- See Markdown Export section for configuration
- Processes 563+ pages, adding significant build time
-
Preview locally: Run the development server and verify content displays correctly
-
Check for broken links: Review console output for link validation warnings
-
Verify cross-references: Ensure all
xref:links resolve correctly
-
Browser compatibility: Test changes in multiple browsers
-
Responsive design: Verify layouts work on different screen sizes
-
JavaScript functionality: Ensure interactive features work as expected
Problem: UI bundle fails to build Solution:
# Clean UI directory and rebuild
rm -rf ui/build ui/node_modules
rm ui-bundle.zip
npm run build:uiProblem: Pages don't appear in navigation Solution:
- Verify
nav.adocentries use correctxref:syntax - Ensure page files exist at the referenced locations
- Check component configuration in
antora.yml
Problem: Changes don't appear after rebuilding Solution:
- Clear your browser cache
- Restart the development server
- Check for AsciiDoc syntax errors
- Verify file path and structure
Problem: Development server takes 30-60+ seconds to rebuild after file changes Solution:
- Check if markdown export is enabled (look for "Markdown export enabled" in console output)
- Markdown generation processes 563+ pages and significantly slows down rebuilds
- Ensure
ENABLE_MARKDOWN_EXPORTis not set totruein your environment - Restart the development server without the environment variable:
npm run start:dev
- Markdown export should be disabled by default for local development
- Only enable it when testing the download functionality:
ENABLE_MARKDOWN_EXPORT=true npm run start:dev
Problem: Content doesn't render as expected Solution:
- Check AsciiDoc syntax
- Verify attributes are correctly defined
- Ensure proper spacing around blocks and elements