Documentation Team Lead
Set up scalable documentation workflows with validation and CI/CD.
Scale your documentation with schemas, validation, remote sources, and CI/CD pipelines. Perfect for teams that need content governance.
Tip
Duration: ~75 min | Prerequisite: Experience managing documentation
Track Contents
Content Collections
Validate frontmatter with typed schemas
Content Collections
Define typed schemas for your content to ensure consistency and catch errors early.
Do I Need This?
No. Collections are optional. Your site works fine without them.
Use collections when:
- You want typos caught at build time, not in production
- Multiple people edit content and need guardrails
- You want consistent frontmatter across content types
Quick Setup
bengal collections init
This createscollections.pyat your project root. Edit it to uncomment what you need:
1 2 3 4 5 6 | |
Done. Build as normal—validation happens automatically.
Built-in Schemas
Bengal provides schemas for common content types:
| Schema | Required Fields | Optional Fields |
|---|---|---|
BlogPost |
title, date | author, tags, draft, description, image |
DocPage |
title | weight, category, tags, toc, deprecated |
APIReference |
title, endpoint | method, version, auth_required, rate_limit |
Tutorial |
title | difficulty, duration, prerequisites, series |
Changelog |
title, date | version, breaking, summary |
Import any of these:
from bengal.collections import BlogPost, DocPage, APIReference
Custom Schemas
Define your own using Python dataclasses:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Validation Modes
By default, validation warns but doesn't fail builds:
⚠ content/blog/my-post.md
└─ date: Required field 'date' is missing
Strict Mode
To fail builds on validation errors, add tobengal.toml:
1 2 | |
Lenient Mode (Extra Fields)
To allow fields not in your schema:
1 2 3 4 5 | |
CLI Commands
1 2 3 4 5 6 7 8 | |
Migration Tips
Existing site with inconsistent frontmatter?
- Start with
strict=Falseto allow extra fields - Run
bengal collections validateto find issues - Fix content or adjust schema
- Switch to
strict=Truewhen ready
Transform legacy field names:
1 2 3 4 5 6 7 8 9 10 11 12 | |
Remote Content
Collections work with remote content too. Use a loader instead of a directory:
1 2 3 4 5 6 7 8 9 | |
See Content Sources for GitHub, Notion, REST API loaders.
Seealso
- Content Sources — GitHub, Notion, REST API loaders
Content Sources
Fetch content from external sources
Remote Content Sources
Fetch content from GitHub, Notion, REST APIs, and more.
Do I Need This?
No. By default, Bengal reads content from local files. That works for most sites.
Use remote sources when:
- Your docs live in multiple GitHub repos
- Content lives in a CMS (Notion, Contentful, etc.)
- You want to pull API docs from a separate service
- You need to aggregate content from different teams
Quick Start
Install the loader you need:
1 2 3 4 | |
Update yourcollections.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Build as normal. Remote content is fetched, cached, and validated like local content.
Available Loaders
GitHub
Fetch markdown from any GitHub repository:
1 2 3 4 5 6 7 8 | |
For private repos, setGITHUB_TOKENenvironment variable or passtokendirectly.
Notion
Fetch pages from a Notion database:
1 2 3 4 5 6 7 8 9 10 11 | |
Setup:
- Create integration at notion.so/my-integrations
- Share your database with the integration
- Set
NOTION_TOKENenvironment variable
REST API
Fetch from any JSON API:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Local (Explicit)
For consistency, you can also use an explicit local loader:
1 2 3 4 5 6 7 | |
Caching
Remote content is cached locally to avoid repeated API calls:
1 2 3 4 5 6 7 8 | |
Cache behavior:
- Default TTL: 1 hour
- Cache directory:
.bengal/content_cache/ - Automatic invalidation when config changes
- Falls back to cache if remote unavailable
CLI Commands
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Environment Variables
| Variable | Used By | Description |
|---|---|---|
GITHUB_TOKEN |
GitHub loader | Personal access token for private repos |
NOTION_TOKEN |
Notion loader | Integration token |
| Custom | REST loader | Any${VAR}in headers is expanded |
Multi-Repo Documentation
A common pattern for large organizations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
Custom Loaders
ImplementContentSourcefor any content origin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Zero-Cost Design
If you don't use remote sources:
- No extra dependencies installed
- No network calls
- No import overhead
- No configuration needed
Remote loaders are lazy-loaded only when you import them.
Other Content Sources
- Autodoc — Generate API docs from Python, CLI commands, and OpenAPI specs
Seealso
- Content Collections — Schema validation for any source
Section 3: Page Not Found
Could not find page:docs/extending/validation/_index
Configuration
Configuring Bengal with bengal.toml
Configuration
Control Bengal's behavior throughbengal.tomland environment-specific settings.
Configuration Methods
Bengal loads configuration from either theconfig/directory (preferred) ORbengal.toml(legacy/simple). Ifconfig/exists,bengal.tomlis ignored.
Overrides apply in order: Base Config → Environment Overrides → CLI Flags.
Quick Start
1 2 3 4 5 6 7 8 9 10 11 12 | |
Configuration Patterns
Best for small sites:
1 2 3 4 5 6 7 8 9 | |
Best for larger sites:
config/
├── _default/
│ ├── site.yaml
│ ├── build.yaml
│ └── theme.yaml
└── environments/
├── production.yaml
└── staging.yaml
Environment Overrides
Run with different settings per environment:
bengal build --environment production
1 2 3 4 5 6 7 | |
Tip
Best practice: Keep development settings inbengal.toml, add production overrides inconfig/environments/production.yaml.
Build Options Reference
Key[build]configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
output_dir |
string | "public" |
Directory for generated files |
clean |
bool | false |
Remove output directory before build |
minify |
bool | false |
Minify HTML/CSS/JS output |
fingerprint |
bool | false |
Add content hash to asset URLs |
validate_templates |
bool | false |
Proactive template syntax validation |
validate_build |
bool | true |
Post-build validation checks |
validate_links |
bool | true |
Check for broken internal links |
strict_mode |
bool | false |
Fail build on any error or warning |
Template Validation
Enablevalidate_templatesto catch template syntax errors early during builds:
1 2 | |
When enabled, Bengal validates all templates (HTML/XML) in your template directories before rendering. This provides early feedback on syntax errors, even for templates that might not be used by every page.
Enable template validation during development for immediate feedback:
1 2 | |
Combine with strict mode in CI pipelines to fail builds on template errors:
1 2 3 | |
When to enable:
- During active theme development
- In CI/CD pipelines
- When debugging template issues
What it catches:
- Jinja2 syntax errors (unclosed tags, invalid filters)
- Unknown filter names
- Template assertion errors
Note
Template validation adds a small overhead to build time. For large sites, consider enabling it only in development and CI environments.
Deployment
Deploy your Bengal site to production
Deploy Your Site
Bengal generates static HTML, CSS, and JavaScript files. This means you can host your site anywhere that serves static files (e.g., GitHub Pages, Netlify, Vercel, AWS S3, Nginx).
The Production Build
When you are ready to ship, run the build command:
bengal build --environment production
This command:
- Loads configuration from
config/environments/production.yaml(if it exists) - Minifies assets (if enabled)
- Generates the
public/directory with your complete site
Common Build Flags
| Flag | Description | Use Case |
|---|---|---|
--environment production |
Loads production config overrides. | Always use for shipping. |
--strict |
Fails the build on warnings (e.g., broken links). | Highly Recommended for CI/CD. |
--clean-output |
Cleans thepublic/directory before building. |
Recommended to avoid stale files. |
--verbose |
Shows detailed logs. | Useful for debugging CI failures. |
Example full command for CI:
bengal build --environment production --strict --clean-output
GitHub Pages
Deploy using GitHub Actions. Create.github/workflows/deploy.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
Netlify
Create anetlify.tomlin your repository root:
1 2 3 4 5 6 | |
Vercel
Configure your project:
- Build Command:
bengal build --environment production - Output Directory:
public - Ensure your
requirements.txtincludesbengal.
Environment Variables
Bengal allows you to inject environment variables into your configuration using{{ env.VAR_NAME }}syntax in your YAML/TOML config files.
config/environments/production.yaml:
1 2 3 | |
Then setAPI_KEYandANALYTICS_IDin your hosting provider's dashboard.
Pre-Deployment Checklist
Before you merge to main or deploy:
- Run
bengal config doctor: Checks for common configuration issues. - Run
bengal build --strictlocally: Ensures no broken links or missing templates. - Check
config/environments/production.yaml: Ensure yourbaseurlis set to your production domain.
1 2 3 | |
Seealso
- Automate with GitHub Actions — Full CI/CD tutorial
- Configuration — Environment-specific settings
- Performance — Optimize build times
Automate with GitHub Actions
Set up automated builds, testing, and deployments using GitHub Actions
Automate with GitHub Actions
Set up continuous integration and deployment (CI/CD) for your Bengal site. Automate builds, run tests, and deploy to production with GitHub Actions.
When to Use This Guide
- You want automated builds on every commit
- You need to run tests before deployment
- You want to deploy to production automatically
- You're setting up preview deployments for pull requests
- You need to validate content and links before publishing
Prerequisites
- Bengal installed
- A Git repository on GitHub
- A hosting provider account (GitHub Pages, Netlify, Vercel, etc.)
- Basic knowledge of YAML
Steps
- 1
Basic Build Workflow
Create
.github/workflows/build.yml:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
name: Build Site on: push: branches: [main] pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.14' - name: Install Bengal run: pip install bengal - name: Build site run: bengal build --environment production --strict - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: site path: public/ retention-days: 1 - 2
Deploy to GitHub Pages
Create
.github/workflows/deploy.yml:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
name: Deploy to Production on: push: branches: [main] permissions: contents: read pages: write id-token: write jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.14' - name: Install Bengal run: pip install bengal - name: Build site run: bengal build --environment production --strict --clean-output - name: Upload artifact uses: actions/upload-pages-artifact@v4 with: path: './public' deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 - 3
Preview Deployments
Create
.github/workflows/preview.yml:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
name: Preview Deployment on: pull_request: branches: [main] jobs: preview: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.14' - name: Install Bengal run: pip install bengal - name: Build site run: bengal build --environment preview --build-drafts - name: Comment PR with preview uses: actions/github-script@v7 with: script: | github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: '✅ Preview build successful! Artifacts available in workflow run.' }) - 4
Add Validation and Testing
Add health checks to your CI pipeline:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
# .github/workflows/test.yml name: Test and Validate on: [push, pull_request] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.14' - name: Install Bengal run: pip install bengal - name: Validate configuration run: bengal config doctor - name: Check for broken links run: bengal health linkcheck - name: Build with strict mode run: bengal build --strict --verbose - 5
Caching for Faster Builds
Add caching to speed up workflows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- name: Cache pip packages uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - name: Cache Bengal build cache uses: actions/cache@v4 with: path: .bengal-cache key: ${{ runner.os }}-bengal-${{ github.sha }} restore-keys: | ${{ runner.os }}-bengal- - 6
Environment-Specific Builds
Create Environment Configs
config/environments/production.yaml:1 2 3 4 5
site: baseurl: "https://example.com" params: analytics_id: "{{ env.GA_ID }}"config/environments/preview.yaml:1 2 3 4 5
site: baseurl: "https://preview.example.com" params: analytics_id: "" # Disable analytics in previewUse Environment Variables
1 2 3
env: GA_ID: ${{ secrets.GA_ID }} API_KEY: ${{ secrets.API_KEY }}
Alternative Platforms
GitLab CI
Create.gitlab-ci.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
Netlify
Createnetlify.toml:
1 2 3 4 5 6 | |
Vercel
Createvercel.json:
1 2 3 4 5 | |
Troubleshooting
Build Failures
Issue: Build fails with "Command not found: bengal"
Solutions:
- Ensure Python 3.14+ is installed
- Check
pip install bengalruns before build - Verify Python path in CI environment
Issue: Build fails with strict mode errors
Solutions:
- Fix broken links:
bengal health check - Fix template errors
- Remove
--strictflag temporarily to identify issues
Deployment Issues
Issue: Files not deploying
Solutions:
- Verify output directory:
public/ - Check build artifacts are uploaded
- Verify deployment permissions
Next Steps
- Deployment Options - Explore other hosting platforms
- Configuration - Environment-specific settings
- Validation - Set up health checks