Home / Getting Started / Format
Format Specification
Wikidown's on-disk format is deliberately minimal: markdown pages, folder-based hierarchy, and .order navigation files. The goal of this specification is to ensure that a repository's documentation is equally readable by humans browsing the file system, AI agents using the CLI, and web-based renderers.
By enforcing these rules, Wikidown prevents the link rot and structural drift that typically plagues flat-file documentation.
The format is built first for GitHub and Jekyll (GitHub Pages): a project wiki that people and different LLM tools share, which renders correctly on github.com and publishes as a static site. It started from Azure DevOps wiki conventions and stays readable by Azure DevOps wikis, but those are no longer the reference point.
1. Page Files and Titles
Every page in the wiki is a standard Markdown file (.md). A page's title is its first # Heading, as plain text (link, code, and emphasis markup is stripped). That's the title readers and tools see: the site nav (in export-html and Jekyll's generated _data/navigation.yml), the export-pdf table of contents and bookmarks, and the title column of wikidown list and wikidown walk.
The file name is the page's path and URL: the title with spaces written as hyphens.
- File on disk:
Release-Notes.md - Heading:
# Release Notes - Rendered title:
Release Notes
So when you create a page titled "Getting Started", the file is named Getting-Started.md (wikidown new --title "Getting Started" does this and writes the # Getting Started heading for you).
Every page should start with a # Heading. Because the title comes from the heading rather than the file name, it can contain characters a file name can't show: a page Attacks-Defense.md headed # Attacks & Defense is titled "Attacks & Defense", and # Move-1 keeps its hyphen. If a page has no # Heading, the file name is the fallback title, with hyphens shown as spaces. A folder with no page of its own shows its folder name.
2. Subpages and Hierarchy
Wikidown supports infinite nesting of pages. To create subpages for a given parent page, you must create a folder with the exact same base name as the parent page's file, located in the same directory.
- Parent page:
/docs/Architecture.md - Subpage folder:
/docs/Architecture/ - Child page:
/docs/Architecture/Data-Model.md
This sibling-folder structure ensures that deleting or moving a parent page can easily include all of its children.
Every subpage folder's parent page should exist and should link every
child in its body — see § Index pages below. WikiRepository.Write will
happily create /Architecture/Data-Model even if /Architecture doesn't
exist yet, which silently orphans the whole subtree: wikidown list /
wikidown search / wikidown check-links' normal link scan all walk the wiki
by descending from already-discovered pages, so a page whose parent was
never created is invisible to all of them. check-links catches this
specific case — see below.
3. Ordering
Alphabetical sorting is rarely the correct way to read documentation. Wikidown uses .order files to explicitly define the navigation hierarchy.
Every folder in the wiki (including the root /docs folder) should contain an .order file. This is a plain text file that lists the base names of the pages in that folder, one per line, from top to bottom.
Example .order file:
Getting-Started
Architecture
API-Reference
If a page exists in the folder but is not listed in the .order file, it is typically appended to the end of the list alphabetically by the renderer.
.order controls navigation-widget ordering only — it has no effect on
GitHub's raw file view, so it's never a substitute for real body links. See
§ Index pages.
4. Internal Links
Internal links between wiki pages must be relative file paths, not
"/"-rooted ones. GitHub resolves a "/"-rooted path like
/Architecture/Data-Model against the repository root, not the wiki root
(and a GitHub Pages project site resolves it against the domain root), so a
link written that way 404s when the page is viewed on github.com or the
published site. A relative path resolves correctly on GitHub, on Pages, and
in Wikidown-aware renderers.
Write the link relative to the linking page's own folder, adjusted for
depth, and include the .md extension:
- Correct (sibling page):
[Read the Data Model](Data-Model.md) - Correct (page in a different folder):
[Read the Data Model](../Architecture/Data-Model.md) - Incorrect:
[Read the Data Model](/Architecture/Data-Model)or[Read the Data Model](/Architecture/Data-Model.md)
Images and other repo assets follow the same rule, e.g.
. Keep them inside the wiki folder:
a file elsewhere in the repo (../../assets/x.png, or /assets/x.png)
isn't published by any route. wikidown check-links --fix copies such
files into .attachments/from-repo/ and relinks them for you.
Run wikidown check-links (see CLI) to walk every page and
verify that relative links and image references resolve to real files; by
default it also flags any "/"-rooted link left in a page body that names
something in the wiki — a title path like /Architecture/Data-Model or a
root path to a file like /.attachments/map.png — and audits that every
folder has a linked index page (§ Index pages). wikidown check-links --fix
rewrites those "/"-rooted links relative to the linking page for you.
This rule only applies to links inside page bodies. Addressing a page
through the CLI — e.g. wikidown read --path /Getting-Started/Format —
still uses the title path, since that's a command argument rather
than a rendered link.
Fixing check-links failures
check-links prints one line per issue:
page:line -> target (reason)
What to do depends on the (reason):
(absolute link (404s on github.com and Pages project sites; run check-links --fix))— the link is "/"-rooted — a/Title/Pathform, or a root path to a file in the wiki such as/.attachments/map.pngor/Bar.md— instead of a relative path. Runwikidown check-links --fix(add--dry-runto preview) to rewrite it relative to the linking page, keeping any#fragment: on page/Cards/Movement,/Rules#setupbecomes../Rules.md#setupand/.attachments/map.pngbecomes../.attachments/map.png. To fix it by hand, rewrite it relative to the linking page's own folder, with the.mdextension. For example, if/Foo.md(at the wiki root) contains[Bar](/Bar)andBar.mdis also at the wiki root, change it to[Bar](Bar.md). If/Sub/Foo.mdlinks to root-level/Bar, it becomes[Bar](../Bar.md). Count the folder hops between the linking page and the target page to get the right number of../.(upper/lower case differs from the file on disk (404s once published))— the target exists, but not with that capitalisation:[Format](format.md)against a file namedFormat.md. Windows and macOS open it anyway; the Linux hosts a wiki is published to do not. Fix the link to match the file name exactly — or, if the file is the one that's wrong, rename it withwikidown move --from Format --to format(case-only renames work on every platform).(broken link)— a "/"-rooted link that names nothing in the wiki (/Nope; reported even with--no-absolute-check), or a relative link/image that doesn't resolve to a real file. This is either a typo in the relative path or a stale link left over from a page that moved or was deleted. Open the linking page's folder and confirm the target filename, hop count, and.md/.attachmentsspelling; fix the path to match the real file. If the target page genuinely no longer exists, either remove the link or point it at wherever that content now lives.(outside the wiki; run check-links --fix)— the link or image points at a file outside the wiki folder (e.g.../../assets/x.png, or/assets/x.pngresolving to the repo root), which no publishing route ships. Runwikidown check-links --fix(add--dry-runto preview): it copies the file byte-for-byte into.attachments/from-repo/, mirroring its path from the repo root, and rewrites the link to point at the copy. Later reports that a copy differs from its source or that no page references it are handled the same way — re-run--fixto refresh or delete it (the copies are Git-tracked, so review the diff).A link that broke because a page moved —
wikidown move(see CLI) automatically rewrites inbound links and the moved page's own relative links when they change a page's path or folder depth. So acheck-linksfailure pointing at a page that was clearly moved usually means one of two things: the move happened before that link-rewriting behavior shipped, or the link was added by hand (e.g. typed into a body) after the move rather than being created throughwikidown move. Either way, fix it the same way as a broken relative link above — retarget it at the page's current path and depth.(no index page <Folder>.md)— a subpage folder exists but its sibling parent page is missing. Create it (wikidown new --path /Folder), then link every child from its body — see § Index pages.(not linked from parent)— the parent page exists but its body never links this child, so a reader browsing rendered markdown (or the raw file on GitHub, where.ordermeans nothing) has no way to reach it. Add a relative link to the child in the parent's body — see § Index pages.
After editing, re-run wikidown check-links to confirm the line is gone.
5. Index Pages
A folder's parent page is that folder's index — the entry point a
reader lands on before descending into its children. Two invariants keep
that entry point real rather than aspirational, both audited by
wikidown check-links (pass --no-index-check to skip this pass):
- The index page must exist.
/Architecture/Data-Modelcan be created without/Architectureever existing — nothing inWikiRepository.Writerequires the parent first. When that happens the whole subtree becomes invisible to every wiki-model-based tool (wikidown list,wikidown search, andcheck-links' own link scan), since they all discover pages by descending from an already-discovered parent.check-linksfinds these orphans by walking the raw filesystem instead, specifically because it can't rely on the page model to see them. - The index page must link every child.
.orderdecides navigation order in Wikidown-aware UIs, but it's invisible on GitHub's raw file view — the only way a reader following links on github.com can reach a child page is a real link in the parent's body.check-linksverifies every*.mdfile directly inside a folder is the resolved target of at least one link (relative or absolute) in that folder's parent page.
A page's own breadcrumb links upward to its
ancestors, but that's a different direction from this check: the
breadcrumb doesn't help a reader on the parent page discover its
children, and it doesn't verify the ancestor pages it links to actually
exist — a folder missing its index page still gets a breadcrumb pointing
at a .md file that isn't there, which is exactly the case index-page
auditing is meant to catch.
6. Breadcrumb Navigation
Every page gets a one-line breadcrumb trail auto-injected as its first
line, always leading back to /Home when the wiki has one:
[Home](../Home.md) / [Encounters](../Encounters.md) / The Sky Hunters <!-- wikidown:breadcrumb -->
This exists because GitHub's own file-path breadcrumb (shown above the raw
file view) reflects the repository path — docs / Encounters / The-Sky-Hunters.md
— not the wiki's page hierarchy or titles. Wikidown's breadcrumb is built
purely from the page's own title chain instead: Home (if it exists) leads,
then each further ancestor is a link (relative, per the convention above),
and the current page's title is the final, unlinked segment — the same
shape GitHub uses, just scoped to the wiki rather than the whole repo.
Key behavior:
- Automatic.
wikidown write(andnew, which writes through the same path) inject or refresh the breadcrumb on every save — there's nothing to opt into or maintain by hand. Write whatever body content you want; the first line is managed for you. - Idempotent. The line carries an HTML comment marker
(
<!-- wikidown:breadcrumb -->) that's invisible when rendered. On every write, whatever was on line one gets discarded if it carries that marker, then a fresh one is computed from the page's current path — so re-saving a page never accumulates duplicate breadcrumbs, and a round-trippedread→ edit →writedoesn't need to preserve the line itself. - Always leads back to
/Home, when the wiki has one.wikidown initseeds a/Homepage as the wiki's entry point; every other page's breadcrumb — including top-level pages, which otherwise have no ancestors — leads with a link to it, so there's always a way back. A wiki with no/Homepage (this repo's own/docspredates that convention) never gets a fabricated link to a page that doesn't exist: top-level pages simply have no breadcrumb, and nested pages' breadcrumbs start from their nearest real ancestor, same as before/Homewas introduced./Homeitself never links to itself. - Moves regenerate it, not just patch it.
wikidown movefully regenerates the breadcrumb for the moved page and every moved descendant, rather than trying to edit the existing links in place — a move can change which ancestors a page has, not just how many../hops reach them, so a patch-in-place approach can leave a structurally wrong (if still technically valid) breadcrumb behind. - Checked like any other link. Breadcrumb links are ordinary
relative markdown links, so
check-linksvalidates them the same way it validates everything else in the body — but only that they resolve. Whether the ancestor page they point at should exist and is properly indexed is § Index Pages' job, not this one. - Wikis that predate
/Home, or predate breadcrumbs entirely, won't have this line until each page is re-saved. Runwikidown backfill-breadcrumbsonce to catch every page up in one pass — see CLI.
7. Markdown Dialect
Wikidown relies on standard CommonMark. There are no proprietary macros or shortcodes required to render the core text. An MVP renderer only needs a standard markdown parser plus the title and file-name rules described above.