antora.yml and playbook keys, annotated
This reference documents the configuration surface you'll touch in a working
docs-as-code setup: the component descriptor (antora.yml), the site
playbook (antora-playbook.yml), and the resource IDs that connect content
together. It covers the keys teams actually use; the
upstream reference remains the exhaustive list.
Everything below applies to Antora 3.x.
The component descriptor: antora.yml
Lives at the root of the documentation component in each content repository
(conventionally docs/antora.yml). Its contents are read per branch —
that's how one repository publishes several versions.
| Key | Required | What it controls |
|---|---|---|
name |
yes | The component's identity in URLs (/widget/…) and resource IDs (widget::page.adoc). Lowercase, stable, never renamed casually: renaming changes every URL and cross-component xref. |
title |
yes | The display name in the UI (navigation, component selector, page breadcrumbs). Safe to change anytime. |
version |
yes | The documented version, as a quoted string ('2.0', not 2.0; YAML reads the latter as a number). Use ~ for a component that shouldn't version at all (release notes, a glossary). |
display_version |
no | What the version selector shows, when it should differ from version, e.g. version: '2.0', display_version: '2.0 LTS'. URLs still use version. |
prerelease |
no | true keeps this version out of the "latest" slot: it builds and is selectable, but latest-version links keep resolving to the newest stable version. Typical on the development branch. |
start_page |
no | The page that answers for the component's root URL. Defaults to index.adoc in the ROOT module; set it only if you deliberately have no index. |
nav |
no | Ordered list of navigation files (e.g. modules/ROOT/nav.adoc). A module without an entry here still publishes pages; they're just unreachable from the sidebar. |
asciidoc.attributes |
no | AsciiDoc attributes scoped to this component and version, such as product names and version numbers for substitution in prose. Branch-varying values belong here, not in the playbook. |
The standard directory layout
The descriptor sits on top of a fixed structure. The directory names are load-bearing — they're how Antora classifies files into families:
docs/
├── antora.yml
└── modules/
├── ROOT/ <- pages at the component root URL
│ ├── nav.adoc
│ ├── pages/ <- *.adoc -> one page each
│ ├── partials/ <- includable snippets (partial$)
│ ├── examples/ <- includable code samples (example$)
│ ├── images/ <- figures (image$)
│ └── attachments/ <- downloadable files (attachment$)
└── admin/ <- extra module -> /widget/2.0/admin/…
└── pages/
Only pages/ is special-cased into output; the other families publish
nothing on their own and exist to be referenced.
The playbook: antora-playbook.yml
Lives in the playbook repository and defines one site build. One playbook, many components.
site
| Key | What it controls |
|---|---|
site.title |
The site-wide title shown in the UI chrome. |
site.url |
The site's public base URL. Required for a correct sitemap, canonical URLs, and (on subpath hosting like GitHub Pages project sites) correctly resolved assets. |
site.start_page |
Which page answers at /, named by a resource ID like widget::index.adoc. Without it, the site root serves a generated 404. |
content
| Key | What it controls |
|---|---|
content.sources[].url |
A git URL (https://…) or local path (../widget; development only, since CI can't see it). |
content.sources[].branches |
Exact names and globs selecting the branches to read: [main, v*]. Negations exclude: "!v1.0". HEAD means the current branch of a local repository, the right value while authoring. |
content.sources[].tags |
Same selection language for tags, for teams that freeze docs at tags instead of branches. |
content.sources[].start_path |
Where the component lives inside the repository (docs). Plural start_paths accepts a list or glob for monorepos holding several components. |
ui
| Key | What it controls |
|---|---|
ui.bundle.url |
The UI bundle zip: layout, styles, header/footer. The default-UI artifact URL serves a moving snapshot, hence the next key. |
ui.bundle.snapshot |
true tells Antora to re-download the bundle when fetching instead of treating the cached copy as immutable. Set it whenever the URL's content can change in place. |
runtime and output
| Key | What it controls |
|---|---|
runtime.fetch |
true refreshes the git cache on every build (the --fetch CLI flag does the same per run). Without it, Antora trusts clones it has already made. |
runtime.log.failure_level |
The build's strictness: error (or warn) makes Antora exit non-zero when anything at that level is logged, such as broken xrefs and missing includes. The key that makes CI trustworthy. |
asciidoc.attributes |
Site-wide AsciiDoc attributes. Component-and-version-specific values belong in antora.yml instead. |
asciidoc.extensions / antora.extensions |
Registered Asciidoctor extensions (e.g. @asciidoctor/tabs) and Antora extensions (e.g. the Lunr search extension), installed via npm in the playbook repository. |
output.dir |
Where the site is written. Default: build/site. |
Resource IDs
Every cross-reference and include names its target by resource ID, not file path. The full form:
version@component:module:family$relative/path.adoc
Every segment except the file is optional, and omitted segments default to "same as the current page", which is why the common cases stay short:
| You write | It means |
|---|---|
xref:install.adoc[] |
Page in the same component, version, and module. |
xref:admin:backup.adoc[] |
Page in the admin module, same component and version. |
xref:widget::index.adoc[] |
Start page of the widget component, latest version (note the double colon: empty module = ROOT). |
xref:1.0@widget::install.adoc[] |
Same, pinned to version 1.0. |
include::partial$prereqs.adoc[] |
Snippet from this module's partials/. |
include::example$config.yml[] |
File from this module's examples/. |
image::diagram.png[Topology] |
Figure from this module's images/. |
Two rules keep teams out of trouble:
- Never link pages with relative file paths. Path links bypass
validation and break when content moves between modules or versions.
If it's a page, it's an
xref:. - Omit the version unless you mean it. An unversioned xref follows the
reader's current version (and the latest when crossing components), which
is almost always the intent. A pinned
1.0@reference is a deliberate, greppable exception.
Related pages
- Your first Antora site: these keys in their natural habitat.
- How Antora assembles a site: why configuration splits between descriptor and playbook at all.