Docs Site
Overview
This directory contains developer documentation for Open mSupply, served as a static site using Zola. Content mirrors the repository's README files and can be extended with standalone documentation.
Site URL: https://dev-docs.msupply.foundation/
Directory Layout
docs/
├── check-docs-structure.sh # CI check script
└── content/ # all site content lives here
├── tools/
│ ├── _index.md # source = "docs" (standalone)
│ └── zola-docs/
│ └── _index.md # this file (source = "docs")
├── build/
│ └── mac/
│ └── _index.md # source = "code"
├── client/
│ ├── _index.md # source = "code"
│ └── packages/
│ ├── common/
│ │ ├── _index.md
│ │ └── ui/
│ │ └── ...
│ └── android/
│ ├── _index.md
│ └── images/
├── server/
│ ├── _index.md # source = "code"
│ └── service/
│ ├── _index.md
│ └── sync/
│ ├── _index.md
│ └── images/
├── docker/
│ └── _index.md
└── standard_reports/
└── _index.mdSetup
Install Zola for macOS
Zola v0.22.1 is recommended. Later versions might work but haven't been tested. If you want to try on the latest version brew install zola would be the easiest.
Option 1 — install via cargo (requires Rust):
cargo install --locked --version 0.22.1 zola
zola --version
Option 2 — install via cargo-binstall (fetches the prebuilt binary, no compile):
cargo binstall zola@0.22.1
zola --version
Option 3 - download binary:
- Download
zola-v0.22.1-x86_64-apple-darwin.tar.gzfrom the v0.22.1 release - Extract and move the
zolabinary to/usr/local/bin/ - In a terminal try run zola. macOS will flag it as unverified — approve it in System Settings → Privacy & Security
- Verify:
zola --version
Serve locally
From the repo root:
cd docs
zola serve
The site will be available at the URL shown in the terminal (usually http://127.0.0.1:1111). Changes to content files trigger an automatic reload.
Adding Content
Every documentation file includes a source field in its front matter. This is a custom field, so Zola requires this to go under the [extra] table.
source = "code"— linked to a README in the codebase. The CI check verifies a matching README exists.source = "docs"— standalone content that lives only on the docs site. No README counterpart expected.
Every page is a directory with an _index.md file. To add standalone content:
- Create a directory under
docs/content/(e.g.tools/zola-docs/) - Add an
_index.mdwithsource = "docs"in the front matter
Example front matter:
+++
title = "Tools"
weight = 90
sort_by = "weight"
template = "docs/section.html"
[extra]
source = "docs"
+++Code-related documentation
Documentation that describes a specific module, package, or area of the codebase should have a README in the repo next to the code it documents. This README is then mirrored to the docs site as an _index.md.
- An
_index.mdindocs/content/at the mirrored path and contains the documentation content. - A pointer README at the original code location that links to the docs site. Previously, this README contained the documentation content.
To add a new one:
- Create a
README.mdin the relevant directory in the repository - Create a matching
_index.mdindocs/content/at the mirrored path (strippingsrc/, see below) - Add Zola front matter with
source = "code"and the title from the first heading - Write your documentation content in the
_index.mdfile - Create a pointer README at the code location
- If the content references images, store them in an
images/directory next to the_index.md
The CI check script will flag any README that doesn't have a corresponding _index.md, and any _index.md with source = "code" that has no matching README.
Example front matter:
+++
title = "Sync - Synchronisation"
weight = 10
sort_by = "weight"
template = "docs/section.html"
[extra]
source = "code"
+++
Example pointer README (at the original location in the repo):
# Sync - Synchronisation
- **Docs site**: https://dev-docs.msupply.foundation/server/service/sync/
- **Source**: [docs/content/server/service/sync/\_index.md](../../../../docs/content/server/service/sync/_index.md)
A relative path is used here so the link still works if someone opens a subfolder (e.g. client/ or server/) as their workspace root.
src/ stripped from paths
The src/ directory segment is a code-only convention and is removed from docs paths. Module names are preserved as-is.
| Repository path | Docs path |
|---|---|
server/service/src/sync/README.md | docs/content/server/service/sync/_index.md |
server/repository/src/db_diesel/README.md | docs/content/server/repository/db_diesel/_index.md |
client/packages/common/src/ui/README.md | docs/content/client/packages/common/ui/_index.md |
Standalone documentation
Documentation that isn't tied to a specific part of the codebase — such as guides, tutorials, architecture overviews, or tool documentation — lives only in docs/content/ with no corresponding README in the repo.
- Create a directory in the appropriate location (e.g.
tools/jenkins/) - Add an
_index.mdwithsource = "docs"in the front matter - The page will appear as a child of the parent section
Nesting content
A topic can be documented as a single page or split across multiple pages. Use a single page when the content is short enough to read in one go. Split it when the topic has distinct subtopics that are easier to find and maintain as separate pages.
For example, a reports section could be one long page:
content/standard_reports/
└── _index.md # everything about reports in one page
Or split into child pages:
content/standard_reports/
├── _index.md # overview: /standard_reports/
├── setup/
│ └── _index.md # child: /standard_reports/setup/
├── creating-reports/
│ └── _index.md # child: /standard_reports/creating-reports/
└── support/
└── _index.md # child: /standard_reports/support/
Nesting can go as deep as needed:
content/standard_reports/
├── _index.md # /standard_reports/
├── support/
│ └── _index.md # /standard_reports/support/
└── setup/
├── _index.md # /standard_reports/setup/
├── mac/
│ └── _index.md # /standard_reports/setup/mac/
└── windows/
└── _index.md # /standard_reports/setup/windows/Images
Images referenced by a file are stored in an images/ directory next to the _index.md that references them. Image paths in the content use ./images/filename.png.
Structure Decisions
Flat content root
Content lives directly under docs/content/. Zola generates URLs from the directory structure inside content/, so docs/content/server/service/sync/_index.md becomes https://dev-docs.msupply.foundation/server/service/sync/. This keeps URLs clean and avoids redundancy with the domain name. New top-level sections (e.g. content/guides/) can be added within the content/ directory.
Pass-through directories
Some directories exist only because a child README is deeper in the tree (e.g. build/ exists only for build/mac/). These are kept to maintain the mirror and accommodate future READMEs at those levels.
CI Check Script
docs/check-docs-structure.sh verifies the docs structure stays in sync with the repository:
- Missing: flags any tracked README that has no corresponding
_index.mdindocs/content/ - Orphaned: flags any
_index.mdwithoutsource = "docs"that has no corresponding README in the repo - Unsafe HTML: flags security and rendering issues in markdown outside of code blocks:
- Bare HTML tags (
<script>,<style>,<iframe>,<img>,<svg>, etc.) — Zola renders these as real HTML, which can break the page DOM and is an XSS risk. Wrap in backticks:`<script>` javascript:URLs in markdown links — direct XSS vector- HTML event handler attributes (
onclick,onerror,onload, etc.) — inline JS execution
- Bare HTML tags (
- Broken links: runs
zola buildand flags any broken internal anchor links (requires Zola installed)
Run it with:
./docs/check-docs-structure.sh
Example failure output:
MISSING: some/new/README.md has no corresponding _index.md at docs/content/some/new/_index.md
ORPHANED: docs/content/some/section/_index.md (no corresponding README — add source = "docs" to frontmatter if this is content not relating to a section of code)
Summary: 68 checked, 2 skipped, 2 errors
Checking internal links...
OK: no broken internal links.
Check failed.
Skipped READMEs:
README.md(root) — not developer module docs.github/workflows/ACTIONS_README.md— GitHub-specific, not developer docsdocs/themes/*— theme vendored files