You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
"Edit this page" links: set repo in a new [edit] section and every page links (in a new tab) to its Markdown source on GitHub, GitLab or Bitbucket, so readers can suggest fixes as pull requests. Translated and versioned pages link to their own source file, self-hosted GitHub and GitLab work via provider, and a page can opt out with "edit_link": false in its front matter. docanvil doctor warns if the settings can't produce working links (#45)
Open in your editor from docanvil serve: while the dev server is running, every page links straight to its source file in your local editor ("Open in editor"), even without an [edit] section. VS Code by default; choose cursor, zed, idea, none, or your own URL template with {path} via serve --editor or DOCANVIL_EDITOR, or let DocAnvil pick it up from $VISUAL / $EDITOR. docanvil build output is unchanged (#78)
Template components: drop a Tera template into theme/components/<name>.html and use it as :::name{…}. A template with a built-in's name restyles that built-in, keeping its data (e.g. tabs)
Components can now be nested — ::::card containing :::note and inline :::lozenge{…} just works
docanvil component list and docanvil component eject <name> to see components and copy a built-in's template into your project
docanvil doctor checks component templates for syntax errors, unusable file names, and {{ body }} without | safe
Breadcrumbs above the page title, following the sidebar: nav groups (linked when they have a page) and labelled separators. Top-level pages don't get one. Override the new breadcrumbs template block to change them
A page's front matter description now shows as a subtitle under its title, as well as in the SEO meta tags
Includes: write shared content once in a fragment (any file or folder starting with _) and drop it into a page with :::include{file="_shared/install.md"}. Fragments can include other fragments, translated pages pick up install.fr.md automatically when it exists, and paths starting with / work the same in every version
Code blocks from files: give an empty code block file="/examples/server.rs" and it shows the real source file, so samples can't drift from the code. Add lines="1-6,30-35" to show just those lines — the skipped ones are marked, and the caption shows the file and ranges
Line numbers on any code block with numbers (or numbers="10" to start elsewhere), or on every block with line_numbers = true under [syntax]. The copy button still copies just the code. title="…" adds a caption to any code block
A missing include, an include loop, a lines range past the end of the file or a full filesystem path such as C:/code/x.rs shows an error box on the page and a build warning, and fails --strict. A fragment that ends inside an unclosed code block gets it closed for it, with the same warning, so the rest of the page still renders
docanvil serve now watches included files that live outside the usual content/theme/asset folders (e.g. ../src/ or /examples/), so editing them live-reloads the page
docanvil doctor checks every :::include and file="…" code block up front, warns about :::include written inside a sentence, translated fragments that are missing a language, and a theme/components/include.html that can never be used, and lists fragments nothing includes. Fragments get the same readability checks as pages
Last updated dates: turn on enabled = true in a new [last_updated] section and every page shows when it last changed, from the newest Git commit touching the page or anything it includes. Set "last_updated": "2026-10-09" in front matter to override the date, or false to hide it, and use source = "front-matter" to skip Git entirely. Dates appear in the page's language, as article:modified_time, and as <lastmod> in sitemap.xml. A shallow clone (the CI default) would give every page the same date, so the build warns about it and --strict fails — fetch full history with fetch-depth: 0. docanvil doctor checks the setup and flags invalid front matter dates
Draft pages: add "draft": true to a page's front matter and it shows in docanvil serve (with a "Draft" banner) but stays out of docanvil build and docanvil export pdf, along with its nav entries, search results and sitemap entry. Links to it from published pages become plain text; set draft_links = "warn" under [build] to get a warning instead, so --strict fails. docanvil build --drafts includes drafts, for preview deploys, and marks them noindex
Redirects: keep old URLs working when pages move. Add "redirect_from": ["old/path"] to the front matter of the page that moved, or map old paths to new ones in a new [redirects] section of docanvil.toml (a target can also be another site). Each old URL gets a small page that forwards readers to the new one (keeping any #anchor) and tells search engines where the page went. Translated and versioned sites get a redirect in every language and version that has the page. Turning on languages or versions moves every URL, so unprefixed = true under [redirects] keeps those links working too. A redirect to a page that doesn't exist, one that would replace a real page, or a loop is a build warning (and fails --strict), and docanvil doctor checks them all
llms.txt for AI tools: turn on enabled = true in a new [llms] section and docanvil build writes llms.txt — your project name, an optional description, and a link to every page grouped like your sidebar, with each page's front matter description — plus llms-full.txt with every page's Markdown in one file (includes filled in, wiki-links turned into real URLs; set full = false to skip it). Translated and versioned sites get a pair per language and version, and the root llms.txt covers the current version in the default language and links to the rest. Drafts are left out, and a page can opt out with "llms": false. docanvil doctor points out when site_url isn't set, since links are then relative
Changed
A page without a front matter title now takes its title from its first # Heading instead of its filename, so sidebar labels, breadcrumbs, search results and the browser tab match the page. URLs are unchanged — only a front matter title or slug affects them. Set label in nav.toml or title in front matter to keep a different label
Built-in component attribute values (such as a note's title or a lozenge's text) are now HTML-escaped, so title="Fish & Chips" renders as written. Put HTML in the body instead
Files and folders whose names start with _ in the content directory are no longer built as pages. They're fragments, meant to be pulled into pages with :::include. If you have a page such as _drafts/idea.md that you do want published, rename it
Text directly after a component's closing ::: (no blank line) is now rendered as Markdown rather than raw HTML
On long pages, the right-hand table of contents only expands sub-headings for the section you're reading (a › marks sections that have them), and keeps the highlighted heading in view as you scroll
Fixed
Directive examples inside fenced code blocks are shown as written instead of being rendered as components
A heading's custom {#id} no longer swallows the blank line after it, which merged the following paragraph into the same block and left the literal {#id} text visible on the page
A component or layout template that {% include %}s itself, directly or through other templates, is now reported as an error naming the loop (in docanvil build and docanvil doctor) instead of crashing the build with a stack overflow (#52)
Wiki-link syntax inside code — fenced blocks and inline `code` spans — is left exactly as written instead of being rewritten or flagged as a broken link. This was tripping up TOML's own [[nav]] table-array syntax in examples; docanvil doctor's broken-link check is fixed the same way (#57)
docanvil doctor --format checkstyle|junit now writes file paths with / on Windows too, so CI tools such as reviewdog can match them to files in the repository