Everything that makes a documentation set look and behave the way it does lives in one object, called documentationConfiguration, which exists on your workspace and on each page type. This page is the complete enumeration of that object — every key, no omissions — plus the page-type fields around it that change how a set behaves, and the inheritance rule that decides which of the two copies a value comes from.
How to read this page
One row per field.
- Stored form matters more than it sounds. Three of the four appearance values are stored as the complete CSS class name (
color-theme-leed), and one is stored bare (charlie) because the build turns it into a template path. Getting this backwards is the most common configuration mistake in the whole object. - Set where is the CMS screen that writes the value. One field is written by the server and should never be typed by hand.
- Inherits answers whether a set falls back to the workspace copy when the page type leaves the field unset. For almost every field it does — see the inheritance rule.
- Read by names what on the published site actually consumes the value, so you can tell what breaks when it is wrong.
Nothing in this object has a schema default. An absent key stays absent, and the consumer’s own fallback — usually do nothing — applies.
The documentationConfiguration fields
| Field | Type | Stored form | Default | Set where | Inherits? | Gated? | Read by | If unset at both levels |
|---|---|---|---|---|---|---|---|---|
layoutName | string | bare name — alpha, bravo, charlie | none; a new workspace’s company configuration sets alpha | Settings → Page Types → the set, or Settings → General for every set | yes | no | The layout partial leed/docs/<name>/base, and the docs-layout-<name> class on <html> | Hard failure. Every page in the set renders one line: documentationConfiguration is missing! |
colorTheme | string | full class name — color-theme-teal | none; a new workspace sets color-theme-blue | same as layoutName | yes | Starter, to introduce a name that is not built in | A class on <html>; the theme’s --docs-* token layer | No --docs-* layer. Every token falls through to your site’s own values, then to Leed’s defaults |
codeTheme | string | full class name — code-theme-github | none; a new workspace sets code-theme-github | same as layoutName | yes | Starter, to introduce a name that is not built in | A class on <html> | Highlight.js still emits its token classes, with no rules behind them — code renders unstyled |
font | string | Tailwind font utility — font-noto-sans | none; a new workspace sets font-open-sans | same as layoutName | yes | Starter, to introduce a name that is not built in | A class on <html> | The set inherits whatever font your site sets |
menus.left | string | a menu id, not a name | bound automatically when the set is created | Settings → Page Types → the set, Left Menu | no — each set owns its own | no | The sidebar, breadcrumbs and previous/next. Also server-side: it is what classifies a menu as a docs menu, what derives the read-only navMenuId, and what folder-path recompute keys off | No sidebar, no breadcrumbs, no pager — and the set’s pages get flat URLs with no folder structure |
menus.top | string | a menu id | none; a new workspace binds its Header Menu | same as layoutName | yes | no | The header navigation | The header nav renders empty; the build logs documentationConfiguration.menus.top was not located! |
menus.bottom | string | a menu id | none; a new workspace binds its Footer Menu | same as layoutName | yes | no | The footer menu columns | The footer renders only its social row and its copyright line |
searchIndexId | string | a search-index id | none | Server-written when the set is created, and when you create a search index naming a set that has none | yes | no | The search asset hashes on every page of the set | Search asset hashes come back empty. Do not hand-author this |
startingPage | string | a page id, as the picker stores it; a site path or absolute URL also works | none | same as layoutName | yes, for the breadcrumb; the root redirect reads only the page type’s own value | no | The breadcrumb home crumb, resolved to the page’s real URL; and, when set on the page type, a 302 redirect from the set root to that page | Breadcrumbs render without a home crumb, and the set root is not redirected |
header.button.text | string | plain text | none; a new workspace sets Get started | same as layoutName | yes | no | The header call-to-action label | With href also absent, no CTA renders at all. With the object present and the text empty, an unlabeled button renders |
header.button.href | string | absolute URL or pageid:<uuid> | none; a new workspace sets / | same as layoutName | yes | no | The header call-to-action target | As above |
logo.light | string | a URL or site path | none | same as layoutName; an uploaded logo may be at most 100 KB | yes | no | The --nav-logo-url custom property used by the docs header and footer logo | The logo box renders empty — it is a background image with no image |
logo.dark | string | a URL or site path | none | same as logo.light | yes | no | The same property inside a dark-scheme media query | Dark mode keeps the light logo |
tabGroups | object | groupId → tabKey → entry | none | Settings → General → Tab Groups only | company only — a page type never stores it | no | The tab renderer at build time, and the editor’s Tab Group menu — both from the same company copy | Tabs still render, with the label the author typed and no icon |
openAPI.snippetLanguages | array | snippet language configs | none; Settings → General seeds cURL, TypeScript, Python and Go | Settings → General | company only | no | The CMS’s OpenAPI import when it generates code samples. The site build does not read it | Generation falls back to the same four languages |
highlighter.extraLanguages | string array | language names | none | no CMS control writes here | company only | — | Nothing at all | Nothing. See the note below |
A complete stored configuration, as committed
This is the documentation half of a real set — the page type’s data file after publishing. The workspace’s own configuration is committed to src/src.11tydata.json and merged underneath it, so any key this file leaves out is inherited from there; tab groups only ever appear in the workspace file.
{
"documentationConfiguration": {
"layoutName": "charlie",
"colorTheme": "color-theme-leed",
"codeTheme": "code-theme-leed",
"font": "font-noto-sans",
"logo": {
"light": "/static/images/logo/leed-logo-p-light.svg",
"dark": "/static/images/logo/leed-logo-p-dark.svg"
},
"menus": { "top": "87cf4837", "left": "leeddocs", "bottom": "IU24ZTE1" },
"header": {
"button": { "text": "Start free", "href": "https://app.leed.ai/auth/sign-up" }
},
"startingPage": "f9618447-4ab8-48f6-9b37-73f2e957b88c"
}
}Where the values end up on the published site
Four of the fields become nothing but a class list. The build joins font, then docs-layout- plus layoutName, then colorTheme, then codeTheme, and puts the result on the root element of every page in the set:
<html lang="en" class="scroll-smooth js-focus-visible leed-documentation font-noto-sans docs-layout-charlie color-theme-leed code-theme-leed">That is the whole mechanism, and it is why the stored forms differ: colorTheme, codeTheme and font are emitted verbatim as classes, so they must be class names, while layoutName is prefixed here and used as a template path elsewhere, so it must be bare. It is also the hook your own CSS attaches to — How Styling Works starts from this element.
Everything else is read by a template: the menu ids by the sidebar, header and footer partials, the logo by a custom property, the starting page by the breadcrumb trail. A template author reaches most of it through a small set of helpers rather than the raw object — those are at Documentation Navigation Helpers.
The inheritance rule, stated once
The mechanism is worth one paragraph, because a developer reading the site repository will otherwise conclude a set’s file is incomplete.
Your workspace serializes to one site-wide data file, src/src.11tydata.json, and its documentationConfiguration is written there when the company settings are published. Each page type serializes its own copy to the set’s data file at src/<slug>/<last-slug-segment>.11tydata.json when the page type is published. The build’s data cascade deep-merges the set’s file over the site-wide one, so a key the set leaves out is read from the workspace. Every writer of either file parses the record and replaces the file whole, so a block hand-written into one is deleted by the next publish. Both files are Leed-owned; hand-editing either one is temporary.
Set values shared by every set on Settings → General, set a value on the page type only where one set should differ, and let the CMS regenerate the files. What the word “default” does and does not mean on the workspace screen is covered at Default Content Configuration.
The three fields that live only on the workspace
tabGroups, openAPI and highlighter are company-wide only. The page-type editor neither shows nor sends them, and a page type never stores them, so there is exactly one copy of each.
For tab groups that means the editor’s Tab Group menu and the build read the same definitions: define a group once, on Settings → General, and it is offered in the editor and renders with its titles and icons on every set. Tab Groups for Consistent Examples owns the detail.
What the front matter of a published page contains
Each page commits as a block of JSON between --- fences — not YAML — followed by the body. On a hand-authored documentation page the keys that carry real values are title, pageTypeId, pageId, publishedAt, modifiedAt and summary.
Three things developers look for and do not find:
- No
categoryand noorder. Hierarchy comes from the menu tree, and ordering from an item’s position in it. (orderis a real key on a tab-group entry, where it sorts what the editor inserts. The two are unrelated.) - No
path. See below. previewOnlyis in the emitted set and defaults tofalse. It has no CMS control, and if it is ever set the page is excluded from production builds and from indexing.
The complete emitted field list, including the keys a documentation page never populates, is at Front Matter Reference.
Where a page’s URL comes from — and the fields that do not set it
path is not a documentationConfiguration field, not a page-type field, and not an emitted front-matter key. A documentation page’s URL is composed: the page type’s slug, then the slugified name of each docs-menu folder above the page, joined by /, then the page’s own slug. The create endpoint ignores a client-supplied path for a menu-bound documentation page type by design, so the URL can never contradict the menu.
The consequence — that renaming a folder physically moves every page beneath it — is worked through at Folders Set Your URLs.
Page type fields that change how a documentation set behaves
The fields above configure the set’s appearance and navigation. These are on the page type itself and change how the set works.
| Field | Type | Default for a docs type | What it changes | Read by | Editable where |
|---|---|---|---|---|---|
slug | string | none — you choose it | The first segment of every URL in the set, and the directory the set’s files live in. May nest (docs/api/1.2.0) for versioned API sets | The build, for every path in the set | Settings → Page Types, until the set is published |
type | documentation | api | posts | documentation | Which machinery applies. documentation and api share the docs menu, the docs layout and this configuration object; posts shares none of it | Everything | Fixed at creation |
layout | string | leed-documentation.hbs | The Handlebars layout every page in the set renders through. Documentation and API types are always set to the system docs layout | The build | Not meaningfully editable for a docs set |
navMenuId | string | derived | A read-only projection of menus.left. It exists so other parts of the CMS can ask “which menu owns this set?” without reading the configuration object | The CMS | Not client-settable — change menus.left instead |
requiredFields | object | summary: true, everything else off | Which fields must be filled before a page can publish | The publish check, in the CMS and over the API | Settings → Page Types |
editorFormattingOptions | object | inert for docs types | Which editor blocks are available. For documentation and api types the toggles are not rendered and the flags are not enforced — every block is available | Only posts types | Not shown for a docs set |
locked | boolean | false | Content Locked: no new pages, and existing pages become read-only. Only an Administrator or Content Publisher can set or clear it | The CMS | Settings → Page Types |
navMenuLocked | boolean | false | Navigation Menu Locked: the set’s pages cannot change URL through its menu — no reordering, no moving, no folder renames, no removal from the nav. Presentation edits stay allowed | The CMS menu editor | Settings → Page Types |
aliases | string array | none | Extra URL prefixes that redirect into the set | The build’s redirect rules | Settings → Page Types |
redirectIndex | string | none | What the set’s root URL does: first, last, a site-relative path, or an external URL | The build’s redirect rules | Settings → Page Types |
noRender | boolean | false | Suppresses rendering of the set’s pages by the site builder, leaving them for a developer’s own templates | The build | Settings → Page Types |
autolink | boolean | true | Whether the set’s pages participate in automatic keyword linking | The build’s content pass | Settings → Page Types |
includeInFeeds | boolean | true | Whether the set appears in feeds and in the AI-support surfaces built from them | The build | Settings → Page Types |
allowRecommendations | boolean | none | Whether the set’s pages are eligible as recommendations | The recommendation engine | Settings → Page Types |
sitemapPriority | number | falls back to 0.99 | The <priority> written into the sitemap for the set’s pages | The sitemap | Settings → Page Types |
labelSiteMapPriority | number | falls back to 0.79 | The same, for the set’s generated label pages | The sitemap | Settings → Page Types |
Every page-type field that is not documentation-specific — and the ones above in their non-documentation meanings — is enumerated at Page Type Reference.
Two of the appearance fields are plan-gated on introducing a name that is not built in, which is a narrower rule than it first appears: echoing the stored value, clearing it, or swapping one built-in theme for another passes on every plan. Themes, Fonts and Code Themes has the exact behavior, and the CSS that makes a custom name mean anything.