Create a documentation site with organized sections, sidebar navigation, and optional external content sources using content_dirs.

πŸ“‚my-docs/
β”œβ”€β”€ πŸ“config.tomlsite config
β”œβ”€β”€ πŸ“‚content/
Β Β Β Β β”œβ”€β”€ πŸ“_index.mdsection: homepage
Β Β Β Β β”œβ”€β”€ πŸ“‚guide/
Β Β Β Β Β Β Β Β β”œβ”€β”€ πŸ“_index.mdsection: getting started
Β Β Β Β Β Β Β Β β”œβ”€β”€ πŸ“installation.mdpage
Β Β Β Β Β Β Β Β β”œβ”€β”€ πŸ“configuration.mdpage
Β Β Β Β β”œβ”€β”€ πŸ“‚reference/
Β Β Β Β Β Β Β Β β”œβ”€β”€ πŸ“_index.mdsection: API reference
Β Β Β Β Β Β Β Β β”œβ”€β”€ πŸ“cli.mdpage
Β Β Β Β Β Β Β Β β”œβ”€β”€ πŸ“config.mdpage
β”œβ”€β”€ πŸ“‚templates/optional overrides
β”œβ”€β”€ πŸ“‚static/images, fonts

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.

πŸ“‚content/guide/
β”œβ”€β”€ πŸ“_index.mdsection: /guide/
β”œβ”€β”€ πŸ“installation.mdpage: /guide/installation/
β”œβ”€β”€ πŸ“‚advanced/
Β Β Β Β β”œβ”€β”€ πŸ“_index.mdsection: /guide/advanced/
Β Β Β Β β”œβ”€β”€ πŸ“caching.mdpage: /guide/advanced/caching/

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
FieldDescription
pathRelative path to the external directory
url_prefixURL prefix for all generated pages (e.g. "docs" produces /docs/...)
templateTemplate for pages from this directory
section_templateTemplate for sections from this directory
sort_bySort order: "title" or "date"
rewrite_linksRewrite 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.

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.