docs-update

star 28

Author, restructure, or update documentation for the Astro/Starlight docs site. Covers ADDING a new docs page or route (MDX + sidebar registration in astro.config.mjs + llms.txt/llms-full.txt inclusion), which prose/MDX and API-reference docs to check after a code change, how to write them, the `<Audience>` and `llmsFull` curation knobs, and regenerating typedoc API docs. Use whenever you create, move, rename, or edit any file under apps/docs/, or after any feature, fix, or refactor that touches user-visible behaviour. (For building a new interactive demo component, use the astro-demo skill instead.)

OysteinAmundsen By OysteinAmundsen schedule Updated 6/7/2026

name: docs-update description: Author, restructure, or update documentation for the Astro/Starlight docs site. Covers ADDING a new docs page or route (MDX + sidebar registration in astro.config.mjs + llms.txt/llms-full.txt inclusion), which prose/MDX and API-reference docs to check after a code change, how to write them, the <Audience> and llmsFull curation knobs, and regenerating typedoc API docs. Use whenever you create, move, rename, or edit any file under apps/docs/, or after any feature, fix, or refactor that touches user-visible behaviour. (For building a new interactive demo component, use the astro-demo skill instead.) argument-hint: optional what-changed description

Documentation Update Guide

Use this skill whenever you touch docs — authoring a brand-new page/route, restructuring or moving pages, or syncing existing docs after a code change. It is the authoritative reference for the docs site's structure, navigation, and the autogenerated LLM corpus — read it before writing, not only as a post-change checklist.

  • Adding or moving a page? Start at Adding a new docs page — it covers the steps that are easy to miss (sidebar registration, llmsFull inclusion, redirects).
  • Changed code and need to sync docs? Use the Quick Decision Matrix below.

llms.txt / llms-full.txt are autogenerated — never hand-edit them. Both are built at docs-build time by the Astro endpoints apps/docs/src/pages/llms.txt.ts and llms-full.txt.ts from the curated MDX/MD doc pages, the demo .astro sources, and JSDoc-derived TypeDoc MDX. You influence their content only by editing those sources — which makes keeping the MDX/curated/source docs accurate more important than before, not less. See Where LLM-file content comes from for the few curation knobs (page frontmatter, ordering, agent preamble). This skill does not manually update the root llms.txt / llms-full.txt.

Adding a New Docs Page

Adding a page is more than dropping an .mdx file — the page is invisible until you register it in the sidebar, and it silently joins the LLM corpus unless you opt it out. Work through all five steps:

  1. Create the MDX page under apps/docs/src/content/docs/grid/ (or a subfolder like grid/plugins/, grid/guides/). Every page needs frontmatter title and description (the description is reused as the page's link blurb in llms.txt). Follow the conventions in How to Write Each Doc Type.

  2. Register it in the sidebar — this is the step most easily forgotten. The navigation tree is hand-curated in apps/docs/astro.config.mjs under starlight({ sidebar: [...] }). A new page does not appear automatically unless it lands in a folder covered by an autogenerate: { directory: ... } entry (currently only grid/guides, grid/plugins, and the TypeDoc grid/api/** trees). For a top-level or curated page, add an explicit entry to the matching group:

    // apps/docs/astro.config.mjs → integrations → starlight → sidebar → 'Grid' group
    { label: 'Introduction', slug: 'grid/introduction' },
    { label: 'AI Assistance', slug: 'grid/ai' },   // ← your new page (slug = path under content/docs/, no extension)
    

    To create a brand-new collapsible section, push a { label, collapsed, items: [...] } object instead. Match the placement to the page's audience (top-level conceptual pages go in the Grid group near Introduction/Getting Started).

  3. Decide LLM-corpus inclusion — by default every prose page is inlined into llms-full.txt and linked in llms.txt. Opt a page out of the full corpus (kept in the index, removed from the inlined dump) with frontmatter llmsFull: false. Use this for pages that teach an agent nothing about building with the grid — e.g. release history. Current opt-outs: grid/changelog.mdx and the three adapter changelog.mdx pages. For a page where only part of the content is human- or agent-only, prefer per-block <Audience> regions instead (see Audience-targeted content).

  4. Place it in the generated ordering (only if it's a new top-level slug or a new section). apps/docs/src/pages/_llm-sources.ts controls how the generated files group and order pages: sectionOf() classifies a slug into a section, and CORE_ORDER sets the reading order for top-level grid/* pages. A new grid/<name>.mdx page that isn't listed in CORE_ORDER sorts to the alphabetical tail of "Core Documentation" — add it to CORE_ORDER if it needs a specific position.

  5. If you moved or renamed a page, add a redirect in astro.config.mjs (redirects: { '/grid/old-path/': '/grid/new-path/' }) so inbound links and bookmarks keep working, and update any internal links per the Internal-link rules.

Then build and run the link check (see Verification).

Quick Decision Matrix

The matrix is grouped by change category. If your change spans multiple categories, apply each matching row — there is no precedence ordering between groups (you update all matching surfaces). The LLM files are intentionally absent: updating the MDX/source docs below regenerates them automatically.

Code / API changes

What Changed Update These Docs
New public API api-reference.mdx, regenerate TypeDoc
New event api-reference.mdx, plugin .mdx if plugin-specific, JSDoc on DataGridEventMap
Breaking change CHANGELOG (migration guide), affected MDX

Plugin changes

What Changed Update These Docs
New plugin Plugin README, plugin .mdx, plugins/index.mdx
Plugin config change Plugin .mdx, plugin README, plugin JSDoc

Adapter changes

What Changed Update These Docs
New adapter feature Adapter README, adapter MDX docs

Theming / styling changes

What Changed Update These Docs
New CSS variable theming.mdx, grid.css registry comment

Workspace / tooling changes

What Changed Update These Docs
Workflow/convention change .github/copilot-instructions.md, AGENTS.md
New skill or tooling .github/skills/, AGENTS.md if Nx-related

Documentation Inventory

Hand-Written (update manually)

Category Location When to Update
Grid README libs/grid/README.md New features, API changes, install instructions
Adapter READMEs libs/grid-{angular,react,vue}/README.md Adapter feature changes
Plugin READMEs libs/grid/src/lib/plugins/*/README.md Plugin feature changes
Core MDX docs apps/docs/src/content/docs/grid/*.mdx Core features, theming, architecture, getting started
Plugin MDX docs apps/docs/src/content/docs/grid/plugins/*.mdx Plugin features, config options, examples
Adapter MDX docs apps/docs/src/content/docs/grid/adapters/*.mdx Framework-specific usage, examples
Demo components apps/docs/src/components/demos/**/*.astro New demos, interactive feature showcases
Copilot instructions .github/copilot-instructions.md Workflow, conventions, architecture changes
Agent instructions AGENTS.md Nx or workspace convention changes
Contributing guide CONTRIBUTING.md Development workflow changes
Architecture doc libs/grid/ARCHITECTURE.md Internal design changes

Auto-Generated (regenerate, don't hand-edit)

Category Generated By Command / Trigger
LLM index (llms.txt) apps/docs/src/pages/llms.txt.ts bun nx build docs
LLM full guide (llms-full.txt) apps/docs/src/pages/llms-full.txt.ts bun nx build docs
TypeDoc API pages typedoc-to-mdx.ts scripts bun nx typedoc <project>
CHANGELOGs release-please Automatic on release PR
Custom elements manifest @custom-elements-manifest/analyzer bun run cem

The LLM files are derived from the MDX/MD doc pages, the demo .astro sources, and the JSDoc-generated TypeDoc MDX — so they stay in sync automatically when you update those sources. Never hand-edit the root llms.txt / llms-full.txt.

How to Write Each Doc Type

Multi-Path Features

When a feature has multiple configuration paths (e.g., CSS vs JS, declarative vs programmatic), apply this checklist to every documentation file that has a dedicated section explaining that feature, a configuration table for it, or a code example using it (not merely a passing hyperlink or index entry) (i.e. the feature's plugin/core MDX page, its README, and any adapter MDX page that documents it in detail). You do not need to touch unrelated documentation files. (The LLM files pick up the change automatically once the MDX is updated.)

For each such file, complete all four steps in order:

  1. State that both paths exist — even if the file only covers one in detail.
  2. Explain when to use which — include a comparison table with trade-offs.
  3. Cross-reference — link to the other doc surface that covers the other path in detail.
  4. Identify the recommended default — guide developers toward the simpler path unless they have specific needs.

Apply this to: icons (CSS vars vs gridConfig.icons), column config (declarative <tbw-grid-column> vs JS columns), features (declarative features vs manual plugins), styling (CSS custom properties vs registerStyles() vs cellClass/rowClass), etc.

Plugin MDX (.mdx)

Plugin MDX pages live in apps/docs/src/content/docs/grid/plugins/. Structure:

---
title: Plugin Name
description: One-line description.
---

import PluginDefaultDemo from '@components/demos/plugin-name/PluginNameDefaultDemo.astro';
import ShowSource from '@components/ShowSource.astro';

## Installation

\`\`\`typescript
import { MyPlugin } from '@toolbox-web/grid/plugins/my-plugin';
\`\`\`

## Basic Usage

<ShowSource component="plugin-name/PluginNameDefaultDemo">
  <PluginDefaultDemo />
</ShowSource>

## Configuration

Auto-generated from the plugin's config interface by \`genPluginConfigTable()\`.

## Events

| Event | Detail | Description |
| ----- | ------ | ----------- |

## API

Public methods and properties.

Plugin JSDoc conventions for auto-generated API docs:

  • ## Configuration Options tables are auto-generated from the constructor's config interface — do not hand-write them in JSDoc
  • ## Programmatic API tables are redundant with auto-generated Methods — do not hand-write them in JSDoc
  • Use {@link TypeName} in hand-written sections (Column Configuration, CSS Custom Properties, Events) to cross-link types
  • Run bun nx typedoc grid after changing JSDoc to regenerate MDX

Plugin README (README.md)

Keep concise — links to docs site for live examples:

# @toolbox-web/grid — Plugin Name

Brief description.

## Usage

\`\`\`typescript
import { MyPlugin } from '@toolbox-web/grid/plugins/my-plugin';
\`\`\`

## Options

| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |

## Documentation

See the [docs site](https://toolboxjs.com/grid/plugins/my-plugin/) for live examples.

Where LLM-file content comes from

llms.txt (concise index) and llms-full.txt (full guide) are autogenerated at docs-build time by apps/docs/src/pages/llms.txt.ts and llms-full.txt.ts. Do not hand-edit the root files — they are derived from:

Source Drives
MDX/MD pages under apps/docs/src/content/docs/grid/** Prose body of llms-full.txt; link entries in llms.txt
Demo .astro under apps/docs/src/components/demos/** Inlined <script> code blocks in llms-full.txt
JSDoc → TypeDoc MDX The linked ## API Reference index (per-symbol .md pages)
libs/grid/src/lib/data/css-variable-registry.* The CSS-variables reference block

So updating the MDX/curated/source docs is how you update the LLM files — keep them accurate and the generated files follow automatically. The only manual curation knobs (touch these only when adding/removing pages or changing ingestion behaviour, not for routine content):

  • <Audience only="human|agent"> regions inside a page — split a single page's content by consumer (see Audience-targeted content below). This is the content-level knob; the three below are page-level / global.
  • Page frontmatter llmsFull: false — omits a page from the llms-full.txt corpus while keeping it linked in llms.txt (used for pages that teach an agent nothing about building with the grid — currently the changelog.mdx pages). See _llm-markdown.ts.
  • Ordering & section maps in apps/docs/src/pages/_llm-sources.tsCORE_ORDER, SECTION_ORDER, API_AREA_ORDER, sectionOf(), apiAreaOf(). Adjust when a new doc section/area needs explicit placement.
  • Agent preamble in apps/docs/src/pages/_llm-agent-preamble.ts — the hand-authored RULE 0 / critical-rules / anti-patterns block prepended to both files. Keep it in sync with the human docs it summarises (Getting Started, Plugins Overview) when those rules change.

To verify the generated output after a docs change, run bun nx build docs and inspect the emitted /llms.txt and /llms-full.txt.

Audience-targeted content

<Audience> (apps/docs/src/components/Audience.astro) lets one MDX page carry content meant for only one consumer. Import it in the page's frontmatter (import Audience from '@components/Audience.astro';) and wrap a block:

<Audience only="agent">

_## Steering heading (note the `_` prefix — see authoring rules)

Steering directive / extra gotcha / copy-paste recipe that helps a code-generating agent.

</Audience>

<Audience only="human">

## Steering heading (plain `##` — renders on the site)

Motivational aside, marketing prose, or screenshot-driven walkthrough that would only dilute agent guidance.

</Audience>
only value HTML docs site Agent corpus (llms-full.txt + per-page .md)
"human" Rendered Stripped (removed entirely)
"agent" Omitted (renders nothing) Kept (wrapper tags unwrapped, inner Markdown flows through)

The two paths are independent: the HTML behaviour is in Audience.astro, the corpus behaviour is in resolveAudienceRegions() (apps/docs/src/pages/_llm-markdown.ts).

When to reach for it — use <Audience> for a portion of an otherwise-shared page. For a whole page that should stay out of the agent corpus, use frontmatter llmsFull: false instead.

Use only="agent" for… Use only="human" for…
Front-loaded "do X, never Y" steering directives the rendered page shouldn't repeat Marketing/motivational prose, "why you'll love this" framing
Extra failure-mode gotchas and edge cases that would clutter the human page Screenshot/GIF-driven walkthroughs that don't translate to text
Copy-paste, full-context code recipes (imports + config) tuned for one-shot generation Onboarding narrative, tone-setting intros, anecdotes
Explicit anti-patterns ("don't add SelectionPlugin just to make a row clickable") Calls-to-action, links to live demos/playgrounds

Authoring rules (enforced by the regex transform):

  • Leave a blank line after the opening tag and before the closing tag so MDX parses the children as Markdown blocks.
  • Headings inside only="agent" blocks must be prefixed with _ — write _## Heading, not ## Heading. Starlight harvests real ## headings into the human page's table-of-contents at compile time (before the runtime conditional render), so a bare ## in an agent-only block leaks a phantom TOC link on the human page. The _ sentinel makes it a non-heading for the human build; the agent-markdown transform (out.replace(/^_(#{1,6} )/, …) in _llm-markdown.ts) strips the _ to restore a real, navigable heading in the corpus. The strip runs in prose only, so _# inside a code fence is left intact. (Human-only blocks render normally, so they use plain ##.)
  • Do not nest <Audience> blocks — the non-greedy match stops at the first </Audience>.
  • Keep agent-only directives consistent with the human docs they shadow; don't let the two audiences drift into contradicting each other.
  • After adding/editing an <Audience> block, run bun nx build docs and confirm the agent content lands in /llms-full.txt (and the human content does not, and vice-versa).

api-reference.mdx (apps/docs/src/content/docs/grid/api-reference.mdx) Events section — Update when:

  • Event cancelability changes (the cancelable events table is curated)
  • Framework-specific listening patterns change

:::note Individual event descriptions, payload types, and code examples are auto-generated from JSDoc in DataGridEventMap — update the JSDoc, not the curated docs. Run bun nx typedoc grid to regenerate. :::

Core MDX Docs (apps/docs/src/content/docs/grid/)

File Contents
index.mdx Landing page, key features
getting-started.mdx Installation, first grid setup
api-reference.mdx Public API reference (properties, methods, events)
theming.mdx CSS custom properties, theme files
core.mdx Core features guide (columns, rows, etc.)
custom-plugins.mdx How to write a plugin
performance.mdx Performance tips
accessibility.mdx A11y features
troubleshooting.mdx Common issues and fixes
demos.mdx Full-featured demo applications
comparison.mdx Feature comparison table
architecture.mdx Internal architecture documentation

Regenerating API Docs

When public API changes (new exports, changed signatures, updated JSDoc):

# Generate TypeDoc JSON and convert to MDX
bun nx typedoc grid
bun nx typedoc grid-angular
bun nx typedoc grid-react
bun nx typedoc grid-vue

Output goes to libs/*/docs/api/ (MDX pages) and libs/*/docs/api-generated/api.json.

Do NOT hand-edit files in docs/api/ or docs/api-generated/ — they are regenerated.

Writing Good JSDoc

JSDoc comments feed into TypeDoc API docs:

/**
 * Configuration for the grid component.
 *
 * @example
 * ```typescript
 * const config: GridConfig = {
 *   columns: [{ field: 'name', header: 'Name' }],
 * };
 * ```
 *
 * @remarks
 * The config is merged with defaults via `mergeEffectiveConfig()`.
 *
 * @see {@link ColumnConfig} for column-level options
 */
export interface GridConfig { ... }

Key tags:

  • @example — Code examples (rendered in docs)
  • @remarks — Extended description
  • @see — Cross-references
  • @deprecated — Mark deprecated APIs with migration info
  • @internal — Exclude from public API docs
  • @since — Version when feature was added
  • @category — Routes exports to different TypeDoc sidebar sections (grid core only, see below)
  • @group — Organizes class members into subsection headings within a page (see below)
  • @fires — Documents events emitted by a method; collected into Events tables

@category and @group — Controlling API Doc Output

The typedoc-to-mdx.ts scripts convert TypeDoc JSON into MDX pages. Two JSDoc tags control where and how exports appear.

@category and @group are only processed by the grid core script (libs/grid/scripts/typedoc-to-mdx.ts). Adapter scripts use hard-coded name lists instead (see below).

@category — API Doc Routing (Grid Core)

Add @category to top-level exports in types.ts, constants.ts, or grid.ts to control which API docs section they land in. The routing logic lives in processCoreModule():

  • @category Plugin DevelopmentGrid/API/Plugin Development/{Kind}/{Name}
  • @category Framework AdaptersGrid/API/Framework Adapters/{Kind}/{Name}
  • Any other value or no @categoryGrid/API/Core/{Kind}/{Name}

Only Plugin Development and Framework Adapters cause routing changes. Other values (e.g., Data Management, Events) are informational — they still route to Core. Check processCoreModule() in libs/grid/scripts/typedoc-to-mdx.ts for the current routing logic.

DataGridElement split: The DataGridElement class is special-cased by genDataGridSplit() — it produces 3 separate MDX documents by filtering members:

  • Public API (DataGridElement.mdx) — members without _ prefix, without @internal, without @category Framework Adapters
  • Plugin API (DataGridElement-PluginAPI.mdx) — _-prefixed members (not __) or @internal Plugin API
  • Framework Adapters (DataGridElement-Adapters.mdx) — members tagged @category Framework Adapters

When adding a new member to DataGridElement, choose the right tag/prefix to place it in the correct document.

@group — Section Headings Within a Page

Add @group GroupName to class members (accessors, methods) to organize them under headings within a generated MDX page. Currently used on DataGridElement members. The genMembersSectionByGroup() function renders groups in a defined order — check the groupOrder array in that function for the current list. Members without @group fall into a generic section at the end.

When adding a new member, use an existing @group value if it fits. If no group fits, create a new one — it will be appended after the ordered groups. If the new group should appear in a specific position, add it to the groupOrder array in genMembersSectionByGroup().

@internal Modifier — Visibility Control

  • @internal alone → excluded from all generated docs
  • @internal Plugin API → included only in the Plugin API document
  • _ prefix (without @internal) → same as @internal Plugin API by convention
  • __ prefix → excluded from all docs (deeply internal)

Adapter Scripts — Hard-Coded Categorization

Adapter scripts (libs/grid-{angular,react,vue}/scripts/typedoc-to-mdx.ts) do NOT use @category. They categorize by checking export names against hard-coded lists (e.g., isDirective() checks a directiveNames array in Angular). Each adapter sorts into folders like Directives/, Components/, Hooks/, Types/, Utilities/, etc.

When adding a new export to an adapter: check the script's categorization functions. If your export doesn't match an existing check (e.g., a new Angular directive), add its name to the corresponding list so it lands in the right folder instead of the catch-all Utilities/. After updating the categorization list, run bun nx typedoc grid-<adapter> (e.g., bun nx typedoc grid-angular) to regenerate the adapter API MDX pages.

Verification

After updating docs:

# Verify docs site builds cleanly
bun nx build docs

# Authoritative broken-link gate (NOT an nx target — Astro does NOT fail on broken links)
node .github/skills/docs-update/check-doc-links.mjs

bun nx build docs passing (EXIT=0) does not mean links are valid — Astro silently renders dead links. node .github/skills/docs-update/check-doc-links.mjs is the real gate; it must report "No broken internal links found." If the script reports broken links, fix every broken link in files you modified as part of this change before committing. For a broken link in a file you did not modify, treat it as pre-existing — do not fix it in this change; note the file and line in your PR description so it can be tracked separately.

Internal-link rules (avoid the common 404s)

  • trailingSlash: 'always' — every internal link MUST end with / (/grid/plugins/shell/, not /grid/plugins/shell).
  • Anchors must match a real heading slug — grep the target page's ^#{1,4} headings before linking to #some-anchor; renamed/removed headings are a frequent source of dead anchors.
  • TypeDoc generates NO page for area roots or export const objects. tools/typedoc-mdx-shared.ts KIND_FOLDER_MAP only emits Classes/, Interfaces/, Functions/, Types/ — there is no per-area index page and no Variables/ folder.
    • /grid/api/framework-adapters/ (area root) · ❌ /grid/api/plugin-development/ · ❌ /grid/api/core/variables/gridclasses/
    • ✅ link to a concrete generated child page (/grid/api/<area>/<kind>/<symbol>/, slug lowercased), e.g. /grid/api/framework-adapters/interfaces/frameworkadapter/ or /grid/api/plugin-development/classes/basegridplugin/.
    • Exported const objects (GridClasses, GridDataAttrs, GridSelectors, GridCSSVars in core/constants.ts) are public API but have NO generated page — keep them as inline code, don't link. Only their TYPE aliases (GridClassName, GridDataAttr) get Types/ pages.

Pre-Commit Documentation Review

Before each commit, quickly scan:

  1. Did I change any public API? → Update api-reference.mdx + JSDoc; regenerate TypeDoc
  2. Did I change any plugin? → Update plugin .mdx and README
  3. Did I add/remove CSS variables? → Update theming.mdx, grid.css registry comment
  4. Did I change events? → Update api-reference.mdx, plugin .mdx, JSDoc on DataGridEventMap
  5. Did I change conventions? → Update copilot-instructions.md

The llms.txt / llms-full.txt files are regenerated from the above sources at docs-build time — there is nothing to hand-edit for them.

Install via CLI
npx skills add https://github.com/OysteinAmundsen/toolbox --skill docs-update
Repository Details
star Stars 28
call_split Forks 2
navigation Branch main
article Path SKILL.md
More from Creator
OysteinAmundsen
OysteinAmundsen Explore all skills →