productdoco/docs
GitHubsign in with github
Reference

productdoco.yaml

One file at the root of your repository. It is what makes the repository a project: name and docs say what to call it and where its documentation lives. Below those sit two independent blocks — nav, which orders, titles and groups the documentation menu, and services, which fills the services board with what the product runs on. Either of those two may be left out.

ProductDoco only ever reads it. Nothing in the app writes to your repository, so this file is the whole way to configure either surface — and it is versioned with your code, read at whatever branch, tag or commit you are looking at.

The two blocks fall back totally: an unreadable nav orservices renders the menu the folder would have produced on its own and a board with no services, and says what it dropped. docs is the exception — it is what confines every read to your documentation folder, so a missing or unusable value is refused rather than guessed at.

Where the file goes

At the root of the repository, not inside the docs folder. It has to sit above that folder because it is the thing that names it: a file findable only inside the folder it defines could never be found at all.

your-repository
your-repo/├── productdoco.yaml       ← this file├── src/└── docs/                  ← whatever `docs:` names    ├── overview.md    ├── integrations.md    └── features/        ├── services.md        └── markdown-rendering.md

A repository your ProductDoco installation can reach that carries this file is a project — there is nothing to create in the app, and nothing about it is stored there. Rename it, or move its documentation, by editing this file.

productdoco.yml works too. If both spellings exist the .yaml one is used and the other is reported as ignored.

Quick start

version is required and is always 1.docs is required for the repository to be readable at all — it is the folder every path below is resolved against, and the boundary every read is confined to. name is optional and falls back to the repository’s own name; so are nav and services.

productdoco.yaml
# productdoco.yaml, at the root of your repositoryversion: 1 # What this project is called, and where its documentation lives.name: Acme Platformdocs: docs # The documentation menu, in the order you want it.nav:  - overview.md  - path: integrations.md    title: Integrations & webhooks  - title: Features    items:      - features/services.md      - path: features/markdown-rendering.md        title: Markdown # The services board.services:  - Plausible  - name: Vercel    icon: vercel    account: team_a1b2c3    cost:      amount: 20      currency: USD      per: month    links:      - title: Dashboard        href: https://vercel.com/productdoco

Without this block the sidebar is built from whatever markdown is in the folder: folders first, then files, each alphabetical, labelled by filename. With it, the menu is the order you write, under the labels you write, grouped however you like.

An entry is either a page or a group, and never both. A page can be written two ways; a group is a title and its items, which hold entries of either shape, up to five levels deep.

the shapes of a nav entry
nav:  # A bare path. The label comes from the filename.  - overview.md   # A path with a label of your own.  - path: integrations.md    title: Integrations & webhooks   # A group. It needs a title, and holds entries of either shape.  - title: Features    collapsed: true    items:      - features/services.md      - title: Rendering        items:          - features/markdown-rendering.md
KeyWhereMeaning
pathentryA markdown file, relative to the docs folder. A bare string is shorthand for it.
titleentryThe sidebar label. Required on a group, optional on a page.
itemsentryMakes the entry a group. A group cannot also have a path.
collapsedgrouptrue renders the group closed. Everything else opens expanded.
  • Paths are relative to the docs folder not the repository root. With docs in docs/, write features/services.md, never docs/features/services.md. Forward slashes only; .. and absolute paths are refused, not resolved.
  • Files you do not list still appear They are appended after everything nav places, keeping their folder structure. The block re-orders and re-labels the menu; it never hides a page.
  • A folder emptied by the config disappears Pull every page out of features/ into groups and the features folder stops rendering; pull out some and it renders with the rest.
  • Anything listed twice appears once At the first place it was listed. Later mentions are reported and dropped.
  • Groups are not folders A group named Features and a real features/ folder can coexist, and a group can collect pages from anywhere in the tree. Only markdown files are ever selectable — a group is a heading, not a page.
  • Only markdown is allowed .md and .mdx, inside the docs folder.
  • A bad nav is dropped whole A block that cannot be trusted falls back to the folder contents, because a half-applied menu is harder to debug than none. A single bad entry only costs that entry.

services: the board

The services a product runs on — with the links you actually open, the account each is billed under, and what it costs. ProductDoco renders this list; it never writes it. Leave the block out and the board is simply empty.

the shapes of a service
services:  # A bare string: a service with nothing but a name.  - Plausible   # Everything a service can carry.  - name: Vercel    icon: vercel    account: team_a1b2c3    cost:      amount: 20      currency: USD      per: month    links:      - title: Dashboard        href: https://vercel.com/productdoco      - title: Logs        href: https://vercel.com/productdoco/logs

Keys

KeyMeaning
nameRequired, written as you would write it. A bare string entry — - Plausible — is shorthand for a service with nothing else.
iconA Simple Icons slug. Optional; without it the name is matched against the 87 built-in services, and anything unmatched shows its initials.
accountThe account the service is billed under. The board can group by it.
costA mapping: amount (a number, required), currency (optional, free text) and permonth or year, defaulting to month. Omit the key and the service shows no cost.
linksA list of title and href pairs. Only http and https addresses are shown; a link with no title falls back to its address.

Rules

  • The board follows the ref you are reading Switch branch or tag in the document bar and the services switch with it, because they come from the file at that commit.
  • Order is yours Services render in the order the file lists them.
  • Names are matched loosely for icons Vercel finds the built-in vercel icon; Vercel (staging) does not, and takes an explicit icon: if you want one. Writing icon: always wins.
  • Two services may share a name They stay separate entries on the board.
  • A yearly cost is divided when the board totals monthly spend.
  • Links are the one real trust boundary and are treated as one: anything that is not an http(s) address is dropped rather than rendered.

When something is wrong

Nothing here fails loudly. A problem costs the smallest thing it can, and the surface it affects says what it dropped in a warning box above itself. The two blocks fail independently: a broken services list never costs you the menu.

In the menu

WarningCause
could not be read as YAMLThe file does not parse. Anchors and aliases are refused on purpose.
needs version: 1The version key is missing, or is a version this release does not know.
must be a mapping with a version and a navThe file's top level is a list or a plain value.
is outside the docs folderThe path escapes the folder, or is absolute.
is not a markdown fileThe path is not .md or .mdx.
was not found at this versionNo such file at the branch, tag or commit being viewed.
is listed more than onceOnly the first mention placed the page.
a group needs a titleA group entry has items but no title.
has both a path and itemsAn entry tries to be a page and a group at once.
the group has nothing left to showEvery item in a group was refused, so the group went with them.
folders more than 5 levels · more than 1000 entries · stopped after 100 foldersThe docs folder itself was too big to crawl whole. These share the same box and are listed first, because they explain any “was not found” below them.

On the board

ProblemWhat happens
Not YAML, not a mapping, or missing version: 1No services, one warning
The file is larger than 64 KBNot read, one warning
services:Not a list — no services, one warning
An entry is not a string or a mapping, or has no nameThat entry is skipped
More than 200 servicesThe rest are skipped
cost is not a mapping, or cost.amount is not a numberThat service renders without a cost
cost.per is neither month nor yearRead as month
A link has no href, or an href that is not http(s)That link is dropped
More than 20 links on one serviceThe rest are dropped

No services: key at all is not a problem, and says nothing. Neither is no nav:.

Limits

A config is a hand-written file, not a data dump, so the numbers are deliberately small.

LimitValue
File size64 KB
nav entries500, nested at most 5 levels
services entries200, with at most 20 links each
Warnings shown10, then a count of the rest

The file is content from a repository like any other, so it is parsed with the YAML core schema only and with alias resolution disabled — no custom tags, and no alias expansion. Every path nav names is checked against the docs folder and then matched to a file the crawl already found; nothing read out of the config is ever used to ask GitHub for anything.

Give this to an agent

Point a coding agent at this page, or paste the spec below into its prompt. It is the whole format in one block — both schemas, the rules and the limits — with nothing on the page it needs to have read first.

spec for an agent
Write productdoco.yaml at the ROOT of this repository, not inside the docsfolder — it names that folder, so it has to sit above it. productdoco.yml isaccepted too; if both exist, .yaml wins. A repository carrying this file is a ProductDoco project. Nothing is stored inthe app: the file is the whole configuration.   version: 1              # required, must be exactly 1  name: <label>           # optional, defaults to the repository name  docs: <folder>          # required: the documentation folder, e.g. docs  branch: <branch>        # optional, defaults to the repository default branch  nav: [ ... ]            # optional: the documentation menu  services: [ ... ]       # optional: the services board docs rules:- A folder inside the repository, written without leading or trailing slashes.- "/", "..", absolute paths, backslashes and empty segments are refused.- Every read is confined to it; an unusable value means the project cannot be  read at all, so this is the one key that is never guessed at. nav — the documentation sidebar, in the order written:  - <path>                # shorthand for { path: <path> }  - path: <path>          # a markdown file, relative to the docs folder    title: <label>        # optional sidebar label  - title: <label>        # a group: title is required    collapsed: false      # optional, true renders the group closed    items: [ ... ]        # required, entries of either shape, max 5 deep nav rules:- Paths are relative to the docs folder, never the repo root: with docs in  docs/, write features/canvas.md, not docs/features/canvas.md.- Forward slashes only. ".." and absolute paths are refused, not resolved.- Only .md and .mdx files can be listed.- An entry has either a path or items, never both.- Files left out of nav still appear, appended after everything nav places,  keeping their folder structure. nav re-orders; it never hides a page.- A path listed twice is used at its first mention only.- A bad nav is dropped whole and the menu falls back to the folder contents. services — the board, in the order written:  - <name>                # shorthand for { name: <name> }  - name: <name>          # required; written as a person would write it    icon: <slug>          # optional Simple Icons slug    account: <id>         # optional; the board can group by it    cost:                 # optional      amount: <number>    # required inside cost      currency: <code>    # optional, free text, e.g. USD      per: month | year   # optional, defaults to month    links:                # optional, max 20      - title: <label>    # optional, falls back to the href        href: <url>       # required, http(s) only services rules:- Without an icon, the name is matched against the 87 built-in services;  anything unmatched shows its initials. An explicit icon always wins.- Two services may share a name; they stay separate entries.- A yearly cost is divided when the board totals monthly spend.- A bad service entry is dropped on its own; the rest of the board renders. Both blocks: no YAML anchors or aliases (alias resolution is disabled, and afile using them is refused whole), 64 KB maximum, and the file is read at thebranch, tag or commit being viewed.Limits: nav 500 entries / 5 levels deep; services 200 entries / 20 links each.

Once the file is committed, open the project and it is picked up on the next read — no setting to flip, and nothing to do in ProductDoco itself.

Ready to point a project at your repository?
GitHubsign in with github