AI-Readable Mode¶
What it is¶
Void generates per-page Markdown mirrors, llms.txt, and llms-full.txt
at build time so AI agents can consume your documentation as clean text.
Every HTML page gets a <link rel="alternate" type="text/markdown"> tag
pointing at its mirror, and a comment marker after <body>.
When to use it¶
The feature is on by default. If your docs are public and you want AI assistants (ChatGPT, Claude, Copilot, etc.) to index your content accurately, leave it enabled. If your docs are private or you don't want AI crawlers, disable it.
How it works¶
Per-page mirrors¶
For every Markdown source page, the plugin writes a .md file containing:
- A watermark header (site name, URL, build timestamp, version)
- The raw Markdown source (front matter stripped)
- A footer comment (
<!-- End of markdown mirror. -->)
The mirror's path depends on url_style:
url_style |
Mirror path example | Source path |
|---|---|---|
"sidecar" (default) |
getting-started/installation.md |
getting-started/installation.md |
"inline" |
getting-started/installation.md |
getting-started/installation/ directory |
HTML decoration¶
Every built HTML page gets two additions:
<!-- before </head> -->
<link rel="alternate" type="text/markdown" href="getting-started/installation.md">
<!-- after <body> -->
<!-- void-ai-readable: getting-started/installation.md -->
llms.txt¶
Generated at the site root (llms.txt). Format:
# My Docs
getting-started/index.html A quick start guide for new users.
getting-started/installation.html How to install the theme.
Each line is <url>\t<description>. Descriptions resolve from:
1. ai_reader.description config override
2. page.meta.description front matter
3. page.title fallback
llms-full.txt¶
All mirrors concatenated into a single file (llms-full.txt), separated by
--- (site) ---. This gives AI agents one file to read for the entire docs.
Sitemap¶
Mirror URLs are appended to sitemap.xml so crawlers discover them.
Configuration¶
theme:
void:
ai_reader:
enabled: true # Master switch (default true)
markup: true # Emit per-page .md mirrors (default true)
url_style: "sidecar" # "sidecar" | "inline" (default "sidecar")
overwrite: false # Never clobber existing mirrors (default false)
auto_title: true # Add # Title when source has no H1 (default true)
exclude: [] # Glob patterns to skip (e.g. "drafts/*.md")
llms: true # Emit llms.txt (default true)
llms_full: true # Emit llms-full.txt (default true)
sitemap: true # Add mirrors to sitemap.xml (default true)
description: "" # Override llms.txt description (default: from page)
watermark:
enabled: true # Emit watermark blocks (default true)
header: true # Metadata at top of mirror (default true)
footer: true # Closing comment at bottom (default true)
text: "Generated by Void for AI agents." # Marker line
include_site: true # Include site_name (default true)
include_url: true # Include canonical URL (default true)
include_generated: true # Include build timestamp (default true)
include_version: true # Include theme version (default true)
Exclude patterns¶
Patterns use Python fnmatch β * matches any characters, ** matches
directories.
Custom llms.txt¶
To provide your own llms.txt, disable the auto-generated one and place
your file in docs/:
Then add docs/llms.txt manually.
Under the hood¶
- File:
void/plugins/void_plugin.py - Defaults:
_VOID_DEFAULT_AI_READER(line ~538) - Mirror generation:
on_post_page()(line ~2953) - llms.txt/full + sitemap:
on_post_build()(line ~3003) - HTML decoration:
_ai_decorate_html()(line ~3132) - URL styles:
_VOID_AI_READER_URL_STYLES(line ~874) β("sidecar", "inline") - Validation:
_validate_ai_reader()(line ~1372) β rejects unknown keys, invalid url_style, non-list exclude - Client-side: none β the entire feature is build-time only. The
ai_readerconfig is injected into#__configbutvoid.jsnever reads it.
Accessibility notes¶
- The
<link rel="alternate">tag is in<head>β screen readers don't announce it, but AI tools and feed readers discover it automatically. - The
<!-- void-ai-readable: ... -->comment is invisible to users. - The watermark header uses HTML comments β it doesn't affect the rendered page.