Build a docs site
Create a documentation site with organized sections, sidebar navigation, and optional external content sources using content_dirs.
What your docs site will look like after this guide.
Initialize the project #
Scaffold a new docs site with the docs template:
zorto init --template docs my-docs cd my-docs
This creates a project with a guide/ section and example pages sorted by title. Start the dev server to see it:
zorto preview --open
Add sections #
Each section is a directory with an _index.md file. Add a reference section:
mkdir -p content/reference
Create content/reference/_index.md:
+++ title = "Reference" sort_by = "title" +++
Then add pages inside it. Create content/reference/cli.md:
+++ title = "CLI reference" +++
## Commands | Command | Description | |---------|-------------| | `build` | Build the site to `public/` | | `preview` | Start dev server with live reload | | `check` | Validate links and config | | `clean` | Remove build output |
Repeat for each page in the section. Zorto generates URLs from the file structure: content/reference/cli.md becomes /reference/cli/.
Nest sections #
Sections can nest to any depth. Create subsections by adding directories with their own _index.md:
mkdir -p content/guide/advanced
Create content/guide/advanced/_index.md:
+++ title = "Advanced" sort_by = "title" +++
Pages inside content/guide/advanced/ appear under /guide/advanced/. Access subsections in templates via section.subsections.
Nested sections create a hierarchical URL structure.
Sort pages #
Control page order with sort_by in the sectionβs _index.md:
sort_by = "title"β alphabetical by title (good for reference docs)sort_by = "date"β newest first (good for changelogs)
For manual ordering, prefix filenames with numbers: 01-installation.md, 02-configuration.md. Zorto includes the full filename in the title slug, so the numbers appear in URLs too. To keep clean URLs, set a custom slug in each pageβs frontmatter:
+++ title = "Installation" slug = "installation" +++
Use custom templates #
Assign a custom template to your docs sections for a different layout than the rest of your site:
# content/guide/_index.md +++ title = "Guide" sort_by = "title" template = "docs-section.html" +++
Individual pages can also use custom templates:
# content/reference/cli.md +++ title = "CLI reference" template = "docs-page.html" +++
Create the corresponding template files in your templates/ directory. They extend base.html like any other template.
Pull in external docs with content_dirs #
If your documentation lives outside the site directory (for example, alongside source code in a library repo), use content_dirs to pull it in without copying files:
# config.toml [[content_dirs]] path = "../docs" url_prefix = "docs" template = "docs.html" section_template = "docs-section.html" sort_by = "title" rewrite_links = true
| Field | Description |
|---|---|
path | Relative path to the external directory |
url_prefix | URL prefix for all generated pages (e.g. "docs" produces /docs/...) |
template | Template for pages from this directory |
section_template | Template for sections from this directory |
sort_by | Sort order: "title" or "date" |
rewrite_links | Rewrite relative .md links to clean URL paths |
With this config, a file at ../docs/guide/installation.md becomes available at /docs/guide/installation/. Zorto treats the external directory as if it were inside content/ β sections, pages, frontmatter, and links all work normally.
Exclude files #
If some external files overlap with manually written content, exclude them:
[[content_dirs]] path = "../docs" url_prefix = "docs" exclude = ["reference/cli.md"]
The excluded file is skipped during content loading. You can then provide your own version at content/docs/reference/cli.md.
Multiple content directories #
You can define multiple content_dirs entries to pull from several sources:
[[content_dirs]] path = "../docs" url_prefix = "docs" sort_by = "title" rewrite_links = true [[content_dirs]] path = "../api-docs" url_prefix = "api" sort_by = "title" rewrite_links = true
Each entry is independent β different URL prefixes, templates, and sort orders.
Add navigation #
Configure top-level navigation in config.toml using menu_items under [extra]:
[extra] menu_items = [ { name = "Guide", url = "/guide/" }, { name = "Reference", url = "/reference/" }, ]
If using content_dirs with a URL prefix, adjust the URLs accordingly:
[extra] menu_items = [ { name = "Guide", url = "/docs/guide/" }, { name = "Reference", url = "/docs/reference/" }, ]
Built-in themes render menu_items as a navigation bar. For sidebar navigation within a section, theme templates use section.subsections and section.pages to build the sidebar automatically.
Enable anchor links #
Add clickable anchor links to headings so readers can link to specific sections:
# config.toml [markdown] insert_anchor_links = "right"
Options: "right" or "none" (default).
Build and deploy #
Build the site for production:
zorto build
The output goes to public/. Deploy it to any static hosting provider β see Deploy your site for platform-specific instructions.
Tip
Run zorto check before deploying to catch broken internal links and configuration issues.
Related guides #
- Content model β sections, pages, and frontmatter in depth
- Configuration reference β full
content_dirsand config field reference - Organize content β section nesting and external content directories
- Customize navigation and footer β menus, logo, social links