Leadtype
Reference

Lint rules

leadtype lint validates source MDX before generation. Run it in CI to fail PRs on schema and link issues before they reach a build. CLI flags are documented in the CLI reference — this page covers the rules, schemas, and library API.

Rules

Grouped by what they catch.

Frontmatter rules

RuleSeverityCatches
schemaerrorRequired field missing or wrong type.
unknown-fieldwarn (default)Top-level field not in the active schema.
parse-errorerrorYAML frontmatter or meta.json won't parse.

unknown-field upgrades to error with --error-unknown. Treat parse-error as the highest priority — it blocks every other check.

RuleSeverityCatches
invalid-linkerrorA /docs/... link points to a route that doesn't exist.
unresolved-placeholdererrorA docs URL still contains {framework} or similar.
cross-framework-linkerrorA framework-scoped page links to another framework's docs.
unflattened-componentwarnA rendered JSX component has no built-in or custom flattener — agents would see raw JSX in the generated markdown.
jsonldwarnThe page's frontmatter would emit invalid JSON-LD — most often a lastModified/last_updated value that isn't a valid date, producing a broken dateModified. Broken schema is worse than none.
geo:heading-skipwarnA heading jumps a level (e.g. H2H4). Keep the hierarchy sequential so answer engines can parse the topic tree.
geo:code-languagewarnA fenced code block has no language label (a bare fence). Tag it with the language (e.g. ts) so engines surface it for the right stack.
geo:image-altwarnAn image has no alt text. Answer engines can't see images — describe what it conveys.

GEO rules

The geo:* rules are the mechanical half of Write for agents & GEO — the structure signals a linter can check. The editorial ones (lead-with-the-answer, question-form headings) can't be linted; that's what the guide is for. All three are warn-level: legitimate exceptions exist, so they never fail the build by default (gate with --max-warnings if you want them to). The same checks feed the Structure portion of leadtype score.

Linting renders MDX through the default remark stack before walking links — same flattening the converter performs, so link checks see the final URLs.

The unflattened-component rule walks the MDX AST, so components inside code fences or inline code are examples — not rendered JSX — and never warn. It recognizes the built-in tag contract plus any custom defineComponentFlattener plugins declared in your config.

Library API

OptionDescription
srcDirRequired. Root of .md, .mdx, and meta.json files.
changelogDirSubdirectory under srcDir validated against the changelog schema.
ignoreGlob patterns relative to srcDir. Defaults shown below.
unknownFieldSeverity"warn" or "error" for fields outside the schema. Default: "warn".
schemas.frontmatterCustom Valibot schema for docs page frontmatter.
schemas.changelogFrontmatterCustom Valibot schema for changelog frontmatter.
schemas.metaCustom Valibot schema for meta.json.

Default ignore patterns: **/shared/**, **/_shared/**, **/_partials/**, **/node_modules/**.

Result shape

Required-field failures are reported as schema violations — that's the public rule for missing or invalid required fields.

Default schemas

Docs frontmatter

FieldRequiredType
titleYesnon-empty string
descriptionNostring
iconNostring
statusNonew, updated, or experimental
deprecatedNonon-empty string
dateNoISO-8601 or parseable date
tagsNostring array
groupNostring or string array
variantsNoarray of { value, label?, href, description? }
relatedNoarray of { title, href, description? }
fullNoboolean

lastModified and lastAuthor are produced by leadtype generate when git metadata is available. Don't author them.

Page status is editorial metadata. Release channels such as canary, RC, preview, and stable should be modeled in build config or transformers, not in source-authored page status.

Changelog frontmatter

FieldRequiredType
titleYesnon-empty string
versionYesSemVer string
dateYesISO-8601 or parseable date
descriptionNostring
iconNostring
typeNorelease, improvement, retired, or deprecation
tagsNostring array
canaryNoboolean
authorsNostring or string array
draftNoboolean

meta.json

FieldRequiredType
pagesYesstring array
titleNonon-empty string
rootNoboolean
iconNostring
defaultOpenNoboolean
nav.sidebarNosection or combined
nav.labelNostring
nav.modeNostring

Custom schemas

Pass a Valibot schema to extend or replace the defaults:

Once you provide a custom schema, unknown-field warnings apply to that schema. Add --error-unknown in CI to keep your contract strict.

Practical guidance

  • Run lint before leadtype generate so content errors fail fast.
  • Use --format github in GitHub Actions and --format json in any other CI.
  • Treat unresolved-placeholder as a content bug first — usually a missing entry in variants or a stale URL template.
  • After a docs move, lint and run meta.json updates together; they drift at the same time.

For wiring lint into pipelines, see Validate in CI.