Built-in Docusaurus schemas
docmeta ships the front matter contract of Docusaurus 3.10 as three built-in schemas, one per content plugin:
| Id | Plugin | Fields | Upstream reference |
|---|---|---|---|
docusaurus:docs:3.10 |
@docusaurus/plugin-content-docs |
25 | Docs front matter |
docusaurus:blog:3.10 |
@docusaurus/plugin-content-blog |
20 | Blog front matter |
docusaurus:pages:3.10 |
@docusaurus/plugin-content-pages |
9 | Pages front matter |
| Property | Value |
|---|---|
| Dialect | Draft 2020-12 |
| Additional properties | Allowed (additionalProperties: true) |
| Required fields | None, in any of the three |
| Reference kind | builtin |
| On by default | No — see turning one on |
Format checks, not presence checks
Section titled “Format checks, not presence checks”Docusaurus marks no front matter field as required in any of the three
plugins. A page with an empty --- block builds fine. These schemas mirror
that: they constrain the shape of every field the plugins document, and demand
none of them.
That makes them the opposite of the taxonomy schemas, which require their key. Turning a Docusaurus schema on cannot fail a page that was already building — it can only catch a value your site would have rejected, or silently mishandled, later.
Why check what Docusaurus already validates
Section titled “Why check what Docusaurus already validates”Docusaurus validates its own front matter at build time, so these schemas are not a substitute for it. They earn their place three ways:
- One report instead of one failure. A Docusaurus build stops at the first
bad file.
docmeta validatereports every offending page in the docs set in one run, with a line number for each. - Before a build, not during one. Validation needs no site config, no install of Docusaurus, and no build step, so it runs in seconds on a pull request that touches ten files.
- Alongside your own standard. These schemas claim neither
typenoraction, so they compose with any of the taxonomy vocabularies. One command holds a page to the generator’s contract and your docs set’s conventions, attributing each failure to the schema that raised it. (Stacking withgoogle:okf:0.1is the one exception — both definetags, and their definitions disagree.)
Fields
Section titled “Fields”| Field | Type | Constraint |
|---|---|---|
id |
string | — |
title |
string | may be empty |
description |
string | may be empty |
slug |
string | — |
sidebar_label |
string | — |
sidebar_position |
number | — |
sidebar_class_name |
string | — |
sidebar_key |
string | — |
sidebar_custom_props |
object | — |
displayed_sidebar |
string or null | — |
pagination_label |
string | — |
pagination_next |
string or null | — |
pagination_prev |
string or null | — |
hide_title |
boolean | — |
hide_table_of_contents |
boolean | — |
toc_min_heading_level |
number | 2–6 |
toc_max_heading_level |
number | 2–6 |
parse_number_prefixes |
boolean | — |
custom_edit_url |
string or null | uri-reference |
keywords |
array of string | — |
image |
string | uri-reference |
tags |
array | string, or object with label and permalink |
draft |
boolean | not both with unlisted |
unlisted |
boolean | not both with draft |
last_update |
object | author and/or date, at least one, nothing else |
| Field | Type | Constraint |
|---|---|---|
authors |
string, object, or array | an authors.yml key, an inline author, or a list of either |
author |
string | deprecated in favor of authors |
author_url |
string | uri-reference, deprecated |
author_image_url |
string | uri-reference, deprecated |
author_title |
string | deprecated |
title |
string | — |
title_meta |
string | — |
sidebar_label |
string | — |
date |
string | — |
description |
string | may be empty |
slug |
string | — |
keywords |
array of string | — |
image |
string | uri-reference |
tags |
array | string, or object with label and permalink |
draft |
boolean | not both with unlisted |
unlisted |
boolean | not both with draft |
hide_table_of_contents |
boolean | — |
toc_min_heading_level |
number | 2–6 |
toc_max_heading_level |
number | 2–6 |
last_update |
object | author and/or date, at least one, nothing else |
| Field | Type | Constraint |
|---|---|---|
title |
string | may be empty |
description |
string | may be empty |
keywords |
array of string | — |
image |
string | uri-reference |
slug |
string | — |
wrapperClassName |
string | — |
hide_table_of_contents |
boolean | — |
draft |
boolean | not both with unlisted |
unlisted |
boolean | not both with draft |
Standalone pages carry no sidebar, pagination, or tag metadata, which is why this set is the smallest of the three.
The rules worth knowing
Section titled “The rules worth knowing”sidebar_position is a number. Quoting it makes it a string, and Docusaurus
rejects it. This is the most common front matter mistake these schemas catch:
✗ docs/install.md /sidebar_position must be number (line 3) [docusaurus:docs:3.10]draft and unlisted are mutually exclusive. Setting both to true is the
one cross-field rule Docusaurus enforces, and the schemas encode it. Either flag
on its own is fine. Because JSON Schema expresses this as a conditional, it
reports twice — once on the field to change, once on the rule as a whole:
✗ docs/install.md /unlisted must be equal to constant (line 4) [docusaurus:docs:3.10] (root) must match "then" schema (line 1) [docusaurus:docs:3.10]Read the first line: drop unlisted (or draft) and both clear.
last_update takes author, date, or both — and nothing else. It is the
only place the schemas forbid unknown keys, because a misspelled autor there
is silently dropped rather than reported.
image and custom_edit_url are URI references. A site-root path like
/img/social/card.png is legal, so these use uri-reference rather than uri,
which would wrongly reject every relative path.
Tag objects need both halves. A tag is either a plain string or an object
carrying label and permalink. Half an object fails.
What these schemas do not check
Section titled “What these schemas do not check”toc_min_heading_level≤toc_max_heading_level. Docusaurus enforces the relationship between the two; JSON Schema cannot express a comparison between sibling fields without a non-portable extension. Each is range-checked to 2–6 on its own, and an inverted pair passes here and fails at build time.- Unknown keys. Docusaurus calls
.unknown()on its own validators, so themes and plugins routinely add front matter of their own. Being stricter than Docusaurus would fail working sites, so these schemas allow extra keys. - Whether a reference resolves.
pagination_next,displayed_sidebar, andauthorsare checked for shape, not for whether the id, sidebar, orauthors.ymlentry they name exists.
Wire them up
Section titled “Wire them up”A Docusaurus site has three content roots with three different contracts, so config overrides are the natural fit:
paths: - docs - blog - src/pagesoverrides: - files: "docs/**" schemas: - docusaurus:docs:3.10 - diataxis:diataxis:1.0 - files: "blog/**" schemas: - docusaurus:blog:3.10 - files: "src/pages/**" schemas: - docusaurus:pages:3.10The first matching override wins, so order them from most to least specific. For a one-off run, pass the id directly:
docmeta validate docs/ -s docusaurus:docs:3.10Versioning
Section titled “Versioning”The version segment is the Docusaurus minor release the contract was
transcribed from, because that is where fields are added — sidebar_key is a
recent arrival. A new minor arrives as a new id rather than a change to
docusaurus:docs:3.10, so upgrading docmeta never retightens a check you
already passed. Pin the id matching the Docusaurus you run, and move it when you
upgrade.