trail.toml reference
trail.toml appears at every level of the tree, with a different schema at each. Unknown keys are build errors everywhere, so a typo fails loudly instead of doing nothing.
The site root #
Required at the site root. Four keys are mandatory.
| Key | Type | Default | |
|---|---|---|---|
sitename | string | required | The site's identity: header wordmark (last word accented), <title> suffix, search placeholder, og:site_name. |
title | string | required | The front page's headline; its og:title and the base for its meta description. |
description | string | required | The front page's standfirst and meta description; the first line of llms.txt. |
footer | string | required | The line at the foot of every page. |
url | string | none | The site's public base URL, e.g. https://learn.peios.org. Trailing slashes are trimmed. |
featured | array of strings | [] | Product slugs, in order. Sorts products, and selects which appear on the front page. |
accent | #rrggbb | theme default | The site accent colour. |
accent_dark | #rrggbb | derived | The dark-mode accent. Derived by mixing accent 75% toward white when absent. |
custom_css | path | none | A stylesheet shipped at /assets/custom.css, loaded after the built-in one. |
favicon | path | none | Shipped at the output root under its own name, linked from every page. |
head_html | path | none | A file injected verbatim at the end of every page's <head>. |
edit_url | string | none | "Edit this page" URL template. Must contain {path}. |
nav | array of tables | [] | Header links. See below. |
passthrough | array of paths | [] | Root entries copied into the output verbatim. See below. |
product_theming | bool | true | Whether each product tints its own pages. |
built_by_trail | bool | true | Whether "Built with Trail." appears under the footer. |
= "Peios Learn"
= "Documentation for everything Peios"
= "Concepts, guides, and reference for the Peios operating system…"
= "https://learn.peios.org"
= "#3b82f6"
= ["peios", "pekit", "provium", "universal-directory", "trail"]
= "Peios Learn — documentation for the Peios project."
[[]]
= "Specs"
= "~peios/pgss"
Validation #
accentandaccent_darkmust be#rrggbb.accent_darkwithoutaccentis an error.custom_css,faviconandhead_htmlare paths relative to the site root, and the file must exist. Naming one is also what makes it legal to keep in the site root; the first path component is what is tolerated there.edit_urlmust contain the literal{path}, which is replaced with the article's source path relative to the site root.- Every slug in
featuredmust name an existing product.
passthrough #
Root entries trail neither builds nor understands, copied into the output as they are:
= ["CNAME", ".well-known", "ads.txt"]
Each entry is a plain relative path naming a file or a directory that exists in the site root; directories are copied whole, nesting included. Naming an entry is also what makes it legal to keep in the site root, exactly as favicon and friends do — so this is how a repository that is also a trail site keeps its CNAME beside its trail.toml.
Errors: an entry that is empty, absolute, or contains ..; one naming something that does not exist; one naming the build output directory.
Passthrough entries are copied last, after everything trail generates, so an entry deliberately named after a generated file replaces it. Naming robots.txt is a supported way to ship your own; naming assets would bury the stylesheet, and trail will not stop you.
[[nav]] #
| Key | Type | |
|---|---|---|
label | string | required. The link text. |
url | string | required. An external URL, a root-relative path, or a ~ page reference. |
References here are resolved strictly at load time — a broken nav link fails the build even under --allow-dangling-links, because site chrome appears on every page.
A shelf is not a link target, so a nav entry cannot point at one — aim at the anthology above it, or a page inside it.
What url unlocks #
Without it: no sitemap.xml, no Sitemap: line in robots.txt, no og:url, relative canonical URLs, and relative outward links in /print bundles. Set it before deploying.
A product #
Required in every <slug>.product directory.
| Key | Type | |
|---|---|---|
title | string | required. The product's display name. |
monogram | string | required. The short string on the product's tile. |
color | #rrggbb | required. The product accent. |
description | string | required. One sentence: the card text, the page standfirst, the llms.txt entry. |
inline_ref | array of strings | Phrases linking to the product's landing page. |
= "pekit"
= "pk"
= "#22c55e"
= "The recipe-driven build and packaging tool."
= ["pekit"]
An anthology #
Required in every .antho directory.
| Key | Type | |
|---|---|---|
title | string | required. |
description | string | required. The card text, the page standfirst, the llms.txt entry. |
inline_ref | array of strings | Phrases linking to the anthology's landing page. |
A book #
Required in every .book directory.
| Key | Type | |
|---|---|---|
title | string | required. |
description | string | required. |
short | string | An abbreviation used where the full title will not fit: the sidebar heading, the card pill, the line above the cover title. |
inline_ref | array of strings | Phrases linking to the book's cover. These may carry a § section suffix in prose. |
= "Peios Generic System Standards"
= "PGSS"
= "Cross-platform system standards from the Peios Project"
= ["PGSS", "Peios Generic System Standards"]
A topic, subfolder or chapter #
Optional. Both keys are optional.
| Key | Type | |
|---|---|---|
title | string | Overrides the slug-derived title. |
inline_ref | array of strings | Phrases linking to the container's first article. Declaring them on a container with no articles is an error. |
= "Reference"
A shelf #
Optional, and takes title only.
| Key | Type | |
|---|---|---|
title | string | Overrides the slug-derived title. |
inline_ref on a shelf is an error. A shelf has no page and no articles of its own, so the phrase would have nowhere to land — declare it on the shelf's items instead.
Derived titles #
Wherever title is optional and absent, it comes from the slug: hyphens become spaces and each word is capitalised. 2--writing-tests.topic becomes "Writing tests"; the-two-gates becomes "The Two Gates". Write the key when that is wrong — acronyms, proper nouns, unusual casing.
inline_ref everywhere #
The key means the same thing at every level: a list of phrases that should become links to this thing wherever they appear in the site's prose. Phrases are exclusive site-wide — two declarers claiming one phrase is an error — and must not be empty, carry leading or trailing whitespace, or contain §. See Inline references.