Configuration
Configuration
All site configuration lives in a single chronicle.yaml file in your project root. The config is validated using Zod — invalid fields produce clear errors at startup.
Project layout
my-docs-site/
├── chronicle.yaml
├── content/ ← latest
│ ├── docs/
│ └── dev/
└── versions/ ← only if versions: is declared
├── v2/
│ └── docs/
└── v1/
├── docs/
└── dev/Content dirs declared in top-level content: are resolved under content/<dir>/ for the latest version; each versions[].content[].dir is resolved under versions/<version-dir>/<dir>/.
Full example
site:
title: My Project Docs
description: Documentation for My Project
url: https://docs.example.com
preset: vercel
logo:
light: ./logo-light.png
dark: ./logo-dark.png
theme:
name: default
content:
- dir: docs
label: Docs
- dir: dev
label: Dev Docs
latest:
label: "3.0"
landing: true
versions:
- dir: v2
label: "2.0"
content:
- dir: docs
label: Docs
- dir: v1
label: "1.0"
landing: true
badge:
label: deprecated
variant: warning
content:
- dir: dev
label: Developer Guide
- dir: docs
label: Docs
api:
- name: REST API (v1)
spec: ./v1-openapi.yaml
basePath: /apis
server:
url: https://api.example.com/v1
navigation:
links:
- label: GitHub
href: https://github.com/myorg/myproject
links:
- label: Support
href: https://support.example.com
search:
enabled: true
placeholder: Search docs...
api:
- name: REST API
spec: ./openapi.yaml
basePath: /apis
server:
url: https://api.example.com
description: Production Server
auth:
type: apiKey
header: Authorization
placeholder: "Bearer token"
redirects:
- from: /old-page
to: /docs/new-page
- from: /legacy/api
to: /apis
permanent: true
analytics:
enabled: true
googleAnalytics:
measurementId: G-XXXXXXXXXX
telemetry:
enabled: true
serviceName: my-docs
port: 9090Reference
site
Required. Site-level metadata.
site:
title: My Documentation
description: Documentation powered by Chronicle| Field | Type | Description |
|---|---|---|
title | string | Site title (navbar, browser tab, canonical metadata). Required. |
description | string | Meta description for SEO and OG. |
url
Optional site URL used for the sitemap and canonical URLs.
url: https://docs.example.comcontent
Required. Content dirs for the latest version. Each entry maps to content/<dir>/ on disk and to /<dir>/... in URLs.
content:
- dir: docs
label: Docs
- dir: dev
label: Dev Docs| Field | Type | Description |
|---|---|---|
dir | string | Folder name under content/. Must be unique. |
label | string | Display label in navigation and landing pages. |
description | string | Optional description shown on landing page cards. |
icon | string | Optional icon identifier for landing page cards. |
latest
Optional metadata for the latest version. Required when versions: is declared.
latest:
label: "3.0"
landing: true| Field | Type | Description | Default |
|---|---|---|---|
label | string | Version label (e.g. 3.0). Shown in the version switcher, or as a static label in the sidebar footer when no versions: are declared. | — |
landing | boolean | true → / renders a landing page listing content dirs. false (default) → / 302s to the first content dir. | false |
versions
Optional list of older versions. Each entry lives under versions/<dir>/ on disk and is reachable at /<dir>/... in URLs.
versions:
- dir: v1
label: "1.0"
landing: true
badge:
label: deprecated
variant: warning
content:
- dir: dev
label: Developer Guide
- dir: docs
label: Docs
api:
- name: REST API (v1)
spec: ./v1-openapi.yaml
basePath: /apis
server:
url: https://api.example.com/v1| Field | Type | Description |
|---|---|---|
dir | string | Folder name under versions/. Doubles as URL prefix. Must be unique. |
label | string | Version label. Shown in the switcher. |
landing | boolean | true → /<dir> renders a landing page; otherwise 302s to the version's first content dir. Default false. |
badge | object | Optional Apsara badge next to the version label. |
badge.label | string | Badge text. |
badge.variant | "accent" | "warning" | "danger" | "success" | "neutral" | "gradient" | Badge colour. Default accent. |
content | {dir, label}[] | Content dirs for this version. Entries may rename, reorder, or omit top-level content dirs. |
api | ApiConfig[] | Version-scoped API specs, rendered at /<dir>/apis/.... Same shape as top-level api:. |
preset
Optional deploy preset. Can be overridden by --preset.
preset: vercel # vercel, cloudflare, or node-serverlogo
Logo with theme-aware variants.
logo:
light: ./logo-light.png
dark: ./logo-dark.png| Field | Type | Description |
|---|---|---|
light | string | Logo path or URL for light theme |
dark | string | Logo path or URL for dark theme |
theme
Theme selection and customization.
theme:
name: default| Field | Type | Description | Default |
|---|---|---|---|
name | 'default' | 'paper' | 'fanfold' | Theme to use | default |
colors | Record<string, string> | Custom color overrides | — |
See Themes for details on each theme.
navigation
Top navbar links and social icons.
navigation:
links:
- label: GitHub
href: https://github.com/myorg/myproject
social:
- type: github
href: https://github.com/myorg/myprojectnavigation.links
| Field | Type | Description |
|---|---|---|
label | string | Link text |
href | string | URL (internal or external) |
navigation.social
| Field | Type | Description |
|---|---|---|
type | string | Icon type: github, twitter, discord, or custom |
href | string | URL |
links
Links shown in the sidebar footer, behind a ? menu button next to the version switcher. Available in the default, paper and fanfold themes.
links:
- label: Go to app
href: https://app.example.com
- label: Support
href: https://support.example.com| Field | Type | Description |
|---|---|---|
label | string | Menu item text |
href | string | URL. Absolute URLs open in a new tab; relative paths navigate in-app |
External links are tagged with UTM query params so the destination can attribute the visit, using the standard names every analytics tool recognises:
| Param | Value |
|---|---|
utm_source | Hostname of the docs site the click came from |
utm_medium | site.title, slugified |
utm_content | Path of the page the link was clicked from |
https://support.example.com?utm_source=docs.example.com&utm_medium=my-documentation&utm_content=%2Fdocs%2FguideExternal links open with noopener (not noreferrer), so the destination also receives a Referer header — but under the browser default referrer policy that header carries only the origin, so utm_content is what identifies the specific page.
Any query string already on href is preserved, and a utm_* param you set yourself is never overwritten. Relative paths are not tagged — they stay on the same origin, so the params would only register as a self-referral. Non-web schemes (mailto:, slack:) are left untouched.
search
Search functionality powered by Fumadocs. Automatically scoped to the active version.
search:
enabled: true
placeholder: Search documentation...| Field | Type | Description | Default |
|---|---|---|---|
enabled | boolean | Enable/disable search | true |
placeholder | string | Search input placeholder | Search... |
When enabled, search is accessible via the navbar button or keyboard shortcut Cmd+K / Ctrl+K. Active version comes from the URL; switching versions scopes the index.
api
OpenAPI specification configuration at the top level applies to the latest version (served at /apis/...). Version-scoped specs live under each versions[].api.
api:
- name: Petstore API
spec: ./petstore.yaml
basePath: /apis
server:
url: https://petstore.swagger.io/v2
description: Production Server
auth:
type: apiKey
header: api_key
placeholder: Enter your API key| Field | Type | Description |
|---|---|---|
name | string | API display name |
spec | string | Path to OpenAPI spec file (JSON or YAML), relative to chronicle.yaml |
basePath | string | URL path prefix for API pages (e.g., /apis) |
icon | string | Optional icon identifier |
server.url | string | Base URL for the API server |
server.description | string | Server description |
auth.type | string | Authentication type (e.g., apiKey, bearer) |
auth.header | string | Header name for auth token |
auth.placeholder | string | Placeholder text in auth input |
redirects
URL redirects for migrating old routes to new ones. Checked before all other routes.
redirects:
- from: /old-page
to: /docs/getting-started
- from: /legacy/api-docs
to: /apis
permanent: true| Field | Type | Description | Default |
|---|---|---|---|
from | string | Old URL path to redirect from | — |
to | string | New URL path to redirect to | — |
permanent | boolean | true for 308 (permanent), false for 307 (temporary) | false |
Use permanent: true when the old URL should never be used again — search engines and browsers will cache the redirect.
analytics
Analytics integration for tracking page views.
analytics:
enabled: true
googleAnalytics:
measurementId: G-XXXXXXXXXX| Field | Type | Description | Default |
|---|---|---|---|
enabled | boolean | Enable/disable analytics | false |
googleAnalytics.measurementId | string | Google Analytics measurement ID | — |
authors
Optional registry of the people who write your docs. Pages reference an entry by
its key in their authors frontmatter, so the details live in one place.
authors:
jane:
name: Jane Doe
bio: Writes about distributed systems.
avatar: /team/jane.png
url: https://github.com/jane
email: jane@example.com| Field | Type | Description | Default |
|---|---|---|---|
name | string | Required. Display name | — |
bio | string | Short description shown on the author's page | — |
avatar | string | Image path for the avatar; initials are used without it | — |
url | string | Profile link, shown on the author's page | — |
email | string | Contact address, shown on the author's page with mailto: | — |
# page.mdx frontmatter
authors: [jane]A frontmatter string that matches no key is still valid — it renders as a plain
name, so occasional contributors need no registry entry. See
Frontmatter for the field itself, and browse the people
writing a site at /authors.
telemetry
Prometheus metrics export via OpenTelemetry. Served on a separate port.
telemetry:
enabled: true
serviceName: my-docs
port: 9090| Field | Type | Description | Default |
|---|---|---|---|
enabled | boolean | Enable/disable telemetry | false |
serviceName | string | OpenTelemetry service name | chronicle |
port | number | Port for Prometheus metrics endpoint | 9090 |
Metrics are available at http://localhost:<port>/metrics in Prometheus exposition format.
Defaults
When chronicle.yaml is missing or fields are omitted, these defaults apply:
site:
title: Documentation
content:
- dir: docs
label: Docs
theme:
name: default
search:
enabled: true
placeholder: Search...