Home / Getting Started / Publishing to GitHub Pages
Publishing to GitHub Pages
GitHub Pages can publish a Wikidown wiki straight from the repo using Jekyll,
its built-in static-site generator — no build pipeline, and nothing to
install: GitHub's servers run Jekyll, your machine never does. wikidown pages
scaffolds everything Jekyll needs into the wiki root, plus a starter theme
with a left-navigation tree that follows your .order files.
Not on GitHub, or want to preview locally? wikidown export-html renders
the same theme in .NET with no Jekyll or Ruby involved — see
Any other host: export-html below, and
Publishing to GitLab Pages for the GitLab
walkthrough. That's how wikidown.org itself is
published: it is this wiki, exported by CI on every change.
Quick start
wikidown pages # run from the repo root; --root docs is the default
git add docs && git commit -m "Publish wiki with GitHub Pages" && git push
Then in GitHub: Settings → Pages → Source "Deploy from a branch", branch
main, folder /docs. The wiki is live at
https://<owner>.github.io/<repo>/ a minute later.
Options:
--title T— site title; defaults to the repo folder name.--force— overwrite theme files you've edited. Careful: this also replaces a customized rootindex.htmlwith the stock redirect.
What it scaffolds
Everything lands inside the wiki root:
| File | Purpose |
|---|---|
_config.yml |
Jekyll config: GFM markdown, the three GitHub-bundled plugins (jekyll-relative-links, jekyll-titles-from-headings, jekyll-default-layout), include: [.attachments] so images work (Jekyll skips dot-folders by default), default layout wikidown. Also the home of Wikidown's own site settings: repository_url (GitHub link in the top bar), favicon, and wikidown.exclude_from_site (below). |
_data/navigation.yml |
The nav tree, generated from .order. Regenerated automatically by the CLI and MCP server on every write/move/delete/reorder once it exists — never edit by hand. |
_layouts/wikidown.html, _includes/nav-tree.html |
The starter theme: top bar, collapsible left nav (active page highlighted, ancestors expanded), content column, footer. Responsive — the nav becomes a slide-in drawer on narrow screens. |
assets/wikidown.css |
Styling, same palette as wikidown.org. Edit freely; pages never overwrites it without --force. |
index.html |
Redirects the site root to /Home.html (or the first top-level page if there is no Home). Replace it with a hand-authored landing page if you want one — wikidown.org does exactly that. |
Customizing any of these — the wiki page layout or the root index.html —
is its own topic: see Customizing the
Theme.
Excluding pages from the published site
Internal notes can stay in the wiki without shipping to the site. List
subtrees under wikidown.exclude_from_site in _config.yml:
wikidown:
exclude_from_site:
- /Meta
- /Testing
This is a publishing concern only: excluded pages remain first-class
for the CLI, MCP server, editor, and check-links — they just produce no
.html and no nav entry. export-html honors it fully;
_data/navigation.yml is generated without them too, so the Jekyll path
hides them from the nav — but GitHub's builder still emits their pages,
so when using built-in Jekyll also list them under the top-level exclude:
key to keep the files out entirely.
One thing the tools can't do for you: body links pointing into an
excluded subtree will 404 on the published site. check-links still
validates them against the repo (where the pages exist), so trim such
links from published pages yourself.
Why it works with the Wikidown format
- Relative
.mdlinks (including the auto breadcrumb) are rewritten to the generated.htmlURLs byjekyll-relative-links. - Page titles come from the first
# Heading, so pages need no YAML front matter. .orderfiles are dotfiles, so Jekyll ignores them; the nav tree reads them via_data/navigation.ymlinstead, because GitHub's Pages builder can't run custom plugins.wikidown check-linksignores_-prefixed folders and folders with no markdown, so the scaffolded files don't trip the index-page audit.
Gotchas
- Liquid in page bodies. Jekyll processes
{{ }}and{% %}everywhere, including code blocks. Wrap such content in{% raw %} … {% endraw %}. (export-htmldoes not run Liquid over page bodies, so it's unaffected.) - Project sites live under
/<repo>/. The theme usesrelative_urleverywhere so this just works; if you serve from a custom domain, setbaseurl: ""in_config.yml. - Don't
.nojekyllwhen using the built-in Jekyll path — that file disables Jekyll and would serve raw.mdfiles. (Anexport-html-based deploy should write.nojekyll, since the output is already final HTML.) - Keep
_data/navigation.ymlcommitted. If it's missing the layout falls back to a flat alphabetical page list.
Any other host: export-html
wikidown export-html --output public
Renders every page through the same _layouts/wikidown.html,
_includes/nav-tree.html, and assets/wikidown.css that GitHub's Jekyll
would use — but in-process, with Markdig
for markdown and Fluid for Liquid.
The output folder is a complete static site: one .html per page, the root
index.html, assets/, .attachments/, and every other static file in
the wiki root (images, install scripts, favicons, extra stylesheets)
copied through verbatim — wiki sources (.md, .order), _-prefixed
Jekyll machinery, other dot-files, and Gemfiles stay out. Nothing to
install beyond the CLI.
- Works with or without having run
wikidown pages. If the wiki root has theme files, they're used (so your customizations apply); anything missing falls back to the built-in copy._config.yml'stitle,description,repository_url,baseurl,favicon, andwikidown.exclude_from_siteare honored. --base-url /prefix— prefix for theme links (stylesheet, nav, redirect) when the site isn't served from the domain root, e.g. GitLab project sites athttps://<group>.gitlab.io/<project>/. Overridesbaseurlin_config.yml. Links inside page bodies are relative and never need it.--title T— overrides the site title.--clean— delete the output folder first, so removed pages don't linger.
Links, titles, and the nav tree match the Jekyll output: relative
.md/.md#anchor links become .html, the title is the first # Heading,
and the sidebar is built from .order (live, not from
_data/navigation.yml, so it's always current).
Local preview is just the export plus any static file server, e.g.
dotnet serve -d public (dotnet tool install -g dotnet-serve) or
npx serve public. Theme authors can iterate on _layouts/assets this
way before pushing to GitHub.
Theme files are written in Jekyll's Liquid dialect; export-html translates
the one construct that differs ({% include file a=b %} / include.a) on
the fly, so a single theme serves both paths. Stick to standard Liquid
filters and tags — Jekyll-only extras like where_exp aren't available in
the .NET renderer.
GitLab Pages
Covered on its own page:
Publishing to GitLab Pages — a one-job
.gitlab-ci.yml that runs export-html in a .NET container. The same
recipe works for any CI that deploys a static folder.
See CLI for the full command list,
Format for the on-disk conventions the generated site relies on,
and Customizing the Theme for swapping the wiki
layout or the root index.html.