Documentation

Frontmatter

Frontmatter

Every page is a .mdx file with a YAML frontmatter block. Leadtype reads three things from it: what the page is, where it lives in the nav, and how to lint it.

Minimum

  • title — required. Non-empty string. Renders as the page heading and as the entry text in llms.txt and the sidebar.
  • description — optional but recommended. Becomes the routing hint in llms.txt. If omitted, the converter synthesizes one from the body during conversion (see convert behavior).
  • group — optional. Slug of a group declared in docs.config.ts. Pages without a group are excluded from the nav and grouped indexes, but still appear in generated markdown and the root llms-full.txt fallback.

How groups become a nav tree

Each page may declare one or more group slugs with group: <slug> or group: [a, b], so pages can be shared across multiple groups. Each group is declared once in docs.config.ts. leadtype generate loads that config automatically when it exists. The intersection produces the nav tree, the section headings in llms.txt, search metadata, and AGENTS.md grouping.

Rendering diagram...

If a page declares a group slug that isn't in docs.config.ts, the build fails with unknown group "<slug>". Same source of truth, no drift.

If you do not have a docs.config.ts, the CLI infers groups from the group: values it finds. That fallback is enough for small docs sets, but use config when you need stable order, descriptions, or nested groups.

Nested groups

Declare children in the config to build deeper trees:

A page sets group: remote-source and lands in that nested slot. Only leaf groups (no children) directly contain pages; non-leaf groups are headings only.

Optional fields

The default lint schema also accepts:

NameTypeDefaultDescription
iconstring-Icon name resolved by your sidebar component.
deprecatedboolean-Marks the page as deprecated in nav and search.
deprecatedReasonstring-Short message paired with deprecated.
experimentalboolean-Marks the page as experimental.
canaryboolean-Hides from stable channels.
newboolean-Highlights the page as recently added.
draftboolean-Excludes from generation entirely.
tagsstring[]-Free-form tags for search facets.
availableInArray<{ framework, url?, title? }>-Cross-framework availability map for TopicSwitcher pages.
fullboolean-Layout hint for docs UIs that support full-width pages.

lastModified and lastAuthor are filled in automatically when you pass --enrich-git to the CLI. Don't author them by hand.

Lint rules

leadtype lint enforces the schema, so violations surface in CI before they reach a build. The relevant rules:

  • schema — a required field is missing or has the wrong type.
  • unknown-field — a top-level field isn't in the schema (warn by default; --error-unknown to fail).
  • parse-error — frontmatter or meta.json doesn't parse.
  • invalid-link — a /docs/... link points to a route that doesn't exist.
  • unresolved-placeholder — a doc URL still contains an unresolved {framework} placeholder.
  • cross-framework-link — a framework-scoped page links to another framework's docs.

See Lint rules for the full reference and how to extend the schema.

What this gives you

Once frontmatter is consistent, the rest of the pipeline works without per-page configuration. The same group: value drives:

  • The sidebar position
  • The llms.txt section
  • Search metadata and AGENTS.md grouping
  • The search filtering UI (if you build one)
  • Cross-framework link checks in lint

One field, one source of truth.