Skip to content
Margo v0.0.5

Purpose

site builds linked HTML pages from a Markdown directory or a .yaml or .yml site config. Directory mode recursively discovers regular .md and .markdown files, rewrites valid Markdown links, and validates anchors and local images. It does not read stdin.

Input and output

Directory mode requires --output-dir. The destination must not already exist. --assets local copies validated assets; inline embeds supported images. On success, the new directory contains page artifacts, required runtime assets, and margo-manifest.json.

The report on stdout contains margo-site-report/v1, artifact count, manifest digest, page records, and an optional policy digest. Build and publication failures go to stderr.

Config mode takes source, output, assets, site identity, base URL or path, layout, navigation, locale, theme, and publication settings from the config. Without --output-dir, configured output is resolved beside that file. An explicit --output-dir changes only the publication destination.

Minimal configured site

margo schema currently emits only the policy and document JSON Schemas; there is no site schema command. A site config is a versioned, closed YAML contract with version: 1. The authoritative v1 field names and validation are the site.Config definition; the repository's showcase.yaml is a complete, larger example.

The following is a complete minimal documentation site. It expects one Markdown source at docs/index.md, a local SVG at assets/logo.svg (the same file can be used for icon), and a local JPEG or PNG at assets/social.jpg. The social image must be exactly 1280×640; Margo validates that dimension, format, and the non-empty alt text before publication.

yaml
version: 1
source: docs
output: dist
assets: local
offline: true
base_path: /docs
site:
  name: Example Docs
  description: A small configured documentation site.
  base_url: https://docs.example.com
  home: index.md
  logo: assets/logo.svg
  icon: assets/logo.svg
  social_image:
    path: assets/social.jpg
    alt: Example Docs preview
layout:
  kind: docs
  default:
    families: [default]
    sidebar: true
    toc: true
    content:
      layout: article
  values:
    family: default
locales:
  default: en
  supported: [en]
navigation:
  mode: file-tree
theme:
  builtin: true
  name: modern
  allow_switch_theme: false
  color_mode: light

Create docs/index.md, put the local assets in the paths above, and build a fresh destination:

sh
mkdir -p docs assets build
cat > docs/index.md <<'MARKDOWN'
---
title: Example Docs
description: A small configured documentation site.
language: en
---

# Example Docs

This page is generated by the configured site contract.
MARKDOWN

margo site ./site.yaml --diagnostics json > build/site-report.json

The command writes dist/index.html, dist/sitemap.xml, dist/llms.txt, and dist/margo-manifest.json; the report is margo-site-report/v1. base_path: /docs affects public URLs and canonical metadata, while output: dist remains a filesystem path beside site.yaml. Set base_path: / for a root deployment. theme.name: modern selects the built-in modern theme; allow_switch_theme and color_mode control its runtime controls and color family. The accepted theme.builtin boolean is shown in the example for the v1 config shape but is not a theme selector by itself. A custom theme instead adds a themes entry with a local css_url and token_catalog, then selects that name. navigation.mode is currently file-tree; locales must include the default locale in its supported list. layout.kind: docs owns search, sidebar, table of contents, pagination, and family navigation. Archive, tag, RSS, and Atom generation remain consumer-owned.

Page publication actions

Pages can retain their Markdown source and publish a pre-rendered PDF through frontmatter:

yaml
margo:
  actions:
    markdown: true
    pdf: true

The PDF action also accepts an object when a branded PDF must include the exact chart-data tables used by margo pdf --print-chart-data:

yaml
margo:
  actions:
    pdf:
      printChartData: true

The object form defaults to pre-rendered; existing boolean and string forms remain compatible. Use pdf: client for browser printing without publishing a PDF artifact. See the margo pdf branding guide for the complete branded publication workflow.

Article publication metadata

Site builds project the document metadata fields authors, publishedAt, modifiedAt, and tags into three stable surfaces: the generated article has an accessible publication-details header (address, labeled time elements, and a tag list). Published and modified timestamps are shown as separate Published/Updated values with a visible separator when both are present; the labels wrap with their values on narrow screens and localize with the page locale. The initial HTML head contains article:* metadata, and each page record in the site report and margo-manifest.json carries the same fields. This lets a blog or news consumer build archive and tag indexes from the route records without duplicating the values in Markdown prose.

For sources that use the common singular names, directory and configured site builds also accept author: Name and date: YYYY-MM-DD (or an RFC 3339 value) as aliases. The canonical names remain preferred when multiple authors or timestamps are needed:

markdown
---
title: A calm release
language: en
authors: [Ana Silva]
publishedAt: "2026-08-25T12:00:00Z"
tags: [operations, release]
---

Margo does not generate archive, tag, RSS, or Atom pages automatically. Route records are deterministic and expose enough metadata for a consumer-owned indexer; ordering, URLs, and publication policy remain the site's responsibility.

Examples

sh
margo site ./docs \
  --output-dir ./build/site-2026-08-20 \
  --assets local \
  --diagnostics json > build/site-report.json
sh
margo site ./site.yaml --diagnostics text > build/site-report.txt

Failures and diagnostics

Markdown table
CodeMeaning
site.output_requiredDirectory mode has no --output-dir
site.output_existsDestination already exists
site.sources_emptyNo public Markdown source was found
site.config_invalidYAML or closed config fields are invalid
site.identity_requiredConfigured public identity is incomplete
site.link_missingA Markdown or generated link target is absent
site.anchor_missingA target fragment has no matching heading
site.asset_externalA site image is not a local site asset
site.asset_outside_rootAn asset escapes the source root
site.output_collisionSources map to the same output path
site.artifact_collisionGenerated artifact paths conflict

Margo builds and validates the complete result in a sibling staging directory, then publishes by a no-replace rename. A failure exits 1 and leaves an existing destination untouched.

Limitations and care

Use a new versioned destination for every build; there is no --force for a site tree. A site build is filesystem publication only. It does not deploy, upload, tag, or release the generated directory.