Skip to main content

Docs style guide

The short version

Lead with the answer. Show it with a diagram or table. Cut every sentence the reader doesn't need.

This site follows the Google developer documentation style guide for voice and grammar. It organizes pages by the Diátaxis page types. The rules below take precedence where they differ.

Write for scanning​

Readers skim. Shape every page so they can find what they need without reading every paragraph.

DoDon't
Open with one or two sentences saying what the page covers and when you'd need it.Open with background or history.
Keep paragraphs to three sentences or fewer.Write blocks of five or more sentences.
Use a list for steps, options or anything with three or more parts.Chain items in a sentence with commas.
Use a table to compare things or to list fields, flags, settings or env vars.Describe each field in its own paragraph.
Use a diagram for any flow, sequence, architecture or state machine.Narrate a flow step by step in prose.
Add a ## heading every few paragraphs, phrased as the reader's question or task.Use long pages with one heading.
Cut filler such as "basically", "in order to", "it's worth noting that" and "simply".Pad sentences.

Voice: use second person ("you"), present tense, active voice and short sentences. Put the condition before the instruction: "To retry a trade, run…".

Formatting toolbox​

NeedUseWorks in
Flow, sequence, architecture, statesMermaid diagram (see Diagrams).md, .mdx
Fields, env vars, endpoints, comparisonsTable.md, .mdx
Warnings, gotchas, prerequisites, a TL;DRAdmonition: :::note, :::tip, :::info, :::warning, :::danger.md, .mdx
Detail most readers can skip, such as full payloads or edge cases<details><summary>…</summary>…</details>.md, .mdx
Commands, config, payloadsFenced code block with a language, plus title="path/to/file" for files.md, .mdx
Alternatives side by side, such as Docker vs Kubernetes<Tabs> / <TabItem>.mdx only
What a UI looks likeScreenshot with synthetic data.md, .mdx

.md files are parsed as CommonMark, so React components such as <Tabs> only work in .mdx. Rename the page to .mdx when you need one.

Shape of each page type​

TypePurposeShape
Explanation (architecture, pipelines)How and why it worksSummary → diagram → one short section per component → "Related" links
How-to (install, deploy, rotate a cookie)Get a task donePrerequisites admonition → numbered steps, one action each → "Verify" step → troubleshooting table
Reference (API, data model, queues, config)Look something upTable per resource or message, generated from code where possible; little or no prose
Tutorial (first run)Learn by doingNumbered steps toward one visible result

Every explanation page and every flow needs at least one diagram. A page that's more than about two screens of prose should be split, or turned into tables and diagrams.

Frontmatter​

Start every page with frontmatter. Don't repeat the title as a # heading; the site renders it from title.

---
title: Lineup updates
description: How a lineup change travels from the API to ESPN and how it is verified.
sidebar_position: 2
---
FieldRequiredPurpose
titleYesPage heading, sidebar label and browser tab title.
descriptionYesOne sentence used for search results and link previews.
sidebar_positionYesOrder within the page's sidebar section, lowest first.

Where a page belongs​

  • In its repo's docs/ folder if it describes one repository: its modules, configuration, data model, bots or runbooks. Update it in the same PR as the code change it describes.
  • In this repo if it spans repositories: architecture, end-to-end flows, integrations, installation, contributing, and networking.

When in doubt, put the detail in the owning repo and link to it from the cross-cutting page.

Each section is a folder under docs/ with an index.md landing page and a _category_.json that sets its sidebar label and position. Add new pages to an existing section rather than creating a top-level one.

Within one repository, link by relative path to the Markdown file, such as [Architecture](../overview/architecture.md) or [Data model](./data-model.md). Docusaurus resolves Markdown file references within the same docs plugin instance.

Across repositories, use the site's absolute route, including any heading anchor: [Message contracts](/worker/message-contracts) or [Style guide](/contributing/docs-style-guide). Do not link to a sibling checkout's Markdown path; plugin instances cannot resolve each other's file references.

RepositoryRoute prefixImported branch
fantasy-project/The site build's commit
fantasy-core-pipeline/coremain
fantasy-browser-worker/workermain
fantasy-web-ui/uimaster
fantasy-infra/inframain

Add slug: / to a repo's docs/index.md to make it the section landing page. If a repo has no root index page, the site generates a landing page from its sidebar. Other pages use their path under docs/ without the Markdown extension unless frontmatter sets a different slug. The build fails on broken Markdown links, site routes and heading anchors, including links across repo instances. Use GitHub URLs for code and files outside docs/; those are not site pages.

Build-time imports​

The site reads each source repo's docs/ directly, including colocated images and linked assets such as openapi.json. The CI checkouts have full history so the last-updated timestamps and edit links refer to the source repo. The local dev server reads sibling checkouts named ../fantasy-*; FANTASY_DOCS_ROOT overrides the directory containing all four checkouts. Restart the server after adding a checkout. Local pages can reflect uncommitted source changes.

Folders named superpowers, plans or working-notes are excluded from the docs plugins. Keep working notes there and do not link to them from published pages.

A push to the source repo's default branch that changes docs/** calls the shared fantasy-project/.github/actions/dispatch-docs action to send the docs-updated repository dispatch to the site. The site rebuilds all four sections, and a nightly build at 08:17 UTC catches missed notifications. See Docs site deploys for credentials and manual rebuilds.

Every source repo's PR template asks Docs updated? Update its docs alongside changes to behavior, API, configuration or workflows, or explain why none are needed.

Web UI component library​

The pages under /ui/components/ are fantasy-web-ui's Storybook build, not docs pages. The docs build runs npm ci && npm run build-storybook in the web-ui checkout, then scripts/add-ui-components.mjs copies storybook-static/ into build/ui/components/ after docusaurus build. A build without it gets a placeholder page.

TaskDo this
Update the libraryMerge the component or story change in fantasy-web-ui. Its dispatch also fires on src/** changes.
Preview it locallyRun npm run build-storybook in the web-ui checkout, then npm run build and npm run serve here. npm start doesn't include it.
Link to itUse pathname:///ui/components/. A plain /ui/components/ link fails the broken-link check, because it isn't a docs route.

Core API explorer​

The pages under /core/api are generated, not written. On every npm run build and npm start, scripts/gen-core-api.mjs reads core's docs/openapi.json, groups untagged routes by their /v1/<area> segment and writes one page per endpoint into the gitignored generated/ folder. Change the spec in core, not the pages.

TaskDo this
Update the explorerMerge the spec change in core. The next site build picks it up.
Preview a spec changeRun npm start with FANTASY_DOCS_ROOT pointing at your core checkout.
Edit the landing pageEdit content/core-api-index.mdx.
Change sidebar groupsAdd tags to the route in core.
No live requests

The explorer's "Send API request" button is off. The site is static behind Cloudflare Access and the API is only reachable inside the cluster. Use the running API's own FastAPI /docs for live calls.

Diagrams​

Draw diagrams in Mermaid in a fenced mermaid code block. Don't commit diagram images. Mermaid diagrams render in light and dark mode and can be diffed and edited in review.

```mermaid
flowchart LR
API[core-pipeline API] -->|waiver_actions| MQ[(RabbitMQ)]
MQ --> WS[waiver_sniper.js]
```
ShowingMermaid type
Components and how they connectflowchart
Messages between services over time, such as API → RabbitMQ → bot → ESPNsequenceDiagram
Lifecycle of a trade, waiver claim or jobstateDiagram-v2
Tables and their relationshipserDiagram
Scheduled jobs across a weekgantt or a table

Keep each diagram to about 12 nodes or fewer. Split a bigger one into an overview plus a detail diagram per part. Label edges with what flows along them, such as a queue name, an HTTP route or an event.

Screenshots are fine for UI pages. Use synthetic fixture data in them. If Mermaid can't express something, such as an annotated UI walkthrough, commit an SVG or PNG next to the page and give it alt text.

No secrets or personal data​

Never put real credentials or personal data in examples, screenshots or logs, even ones that look expired:

  • No API keys, tokens, passwords, bot keys or connection strings with real credentials. Use obvious placeholders such as <GROQ_API_KEY> or changeme.
  • No ESPN cookies (espn_s2, SWID) or saved browser session state.
  • No personal identifiers: real names, emails, league or team IDs that identify a person, or IP addresses and hostnames from a real deployment.

If something sensitive is committed, rotate it first. Removing it from the page does not remove it from Git history.

Queue contract explorer​

The queue contract explorer renders core's docs/asyncapi.yaml with @asyncapi/react-component. The site imports the spec at build time from the same FANTASY_DOCS_ROOT checkout as core's prose; no broker connection is needed. The component loads in the browser using the package's browser bundle, which includes the parser's browser dependencies. A checkout without the spec shows a placeholder.

Update message fields in core's spec and run its contract tests when publishers change. Keep delivery, idempotency and recovery prose in the source repos, linking to the explorer for field schemas and examples.