Skip to content
Product DocumentationDocumentation
All products

Writing Documentation

Everything in this portal is Markdown or MDX in src/content/docs/, partitioned by product. Writing documentation means creating a file and adding one line to the navigation config.

Create src/content/docs/bpp/sales/credit-note.mdx:

src/content/docs/bpp/sales/credit-note.mdx
---
title: Credit Note
description: Reverse all or part of a confirmed sales invoice.
---
A credit note reverses a confirmed sales invoice, in whole or in part.
## Opening the screen
<NavPath path="Sales > Transactions > Credit Note" />
<Screenshot
src="/images/bpp/sales/credit-note.svg"
caption="The Credit Note screen."
alt="Credit Note screen with the source invoice selected."
/>
<Tip>
Always raise the credit note from the source invoice rather than from scratch — the lines, rates and tax are then guaranteed to match.
</Tip>

No imports. Every component listed in the component library is available in any page automatically.

Then add it to the navigation in src/config/projects.ts:

src/config/projects.ts
{
label: 'Sales',
icon: 'cart',
index: 'bpp/sales',
items: [
{ label: 'Sales Invoice', slug: 'bpp/sales/sales-invoice' },
{
label: 'Credit Note',
slug: 'bpp/sales/credit-note',
summary: 'Reverse all or part of a confirmed invoice.',
},
],
},

That one entry gives you the sidebar row, the breadcrumb trail, the prev/next pagination, the card on the section overview page, and inclusion in the search index.

Only title is required. The rest is optional and mostly feeds the training metadata under the page heading.

Page frontmatter
FieldTypeRequiredDefaultDescriptionNotes
titleStringYes—The page heading and the browser tab title.
descriptionStringNo—Meta description and Open Graph description. Write one — it is what shows in search results.One sentence
levelEnumNo—Beginner, Intermediate or Advanced. Shown as a chip.
audienceStringNo—Who the page is written for, e.g. Sales Executive.
readingTimeStringNo—Rough time to work through, e.g. 10 min.
appliesToStringNo—Which release the page was verified against.Update this as you re-verify
keywordsString[]No—Extra terms for the search index.
sidebarObjectNo—Starlight sidebar overrides — order, label, badge.
pagefindBooleanNotrueSet false to exclude the page from search.
draftBooleanNofalseExcluded from production builds; visible in dev.

Page frontmatter

The custom fields are declared in src/content.config.ts. Add your own there and they are available in frontmatter immediately.

Every generated page follows the same structure, and keeping to it is what makes the manual feel authored rather than assembled.

The standard page structure
StepActionResult
1Lead paragraphWhat this is and why it matters, in two sentences
2## OverviewHow it fits with everything else
3## Prerequisites<Prerequisites> — what must already be true
4## Opening the screen<NavPath> and a <Screenshot>
5## Procedure<Steps> with <Step> children
6Expected result<ExpectedResult> — how to tell it worked
7## Field reference<FieldTable>
8## Important notesCallouts, strongest first
9## Common problems<Accordion> of symptom and fix
10## Frequently asked questions<FAQ>
11## Related documentation<RelatedDocumentation>

The standard page structure

Images live in public/images/<product>/<section>/, mirroring the content tree, and are referenced by absolute path.

Drop the file in and pass dual={false}, because a real capture has no dark twin:

<Screenshot
src="/images/bpp/sales/credit-note.png"
dual={false}
caption="The Credit Note screen."
alt="Credit Note screen with the source invoice selected and two lines being reversed."
/>

The portal ships generated mock screenshots so it looks finished before anyone captures a real screen. They are produced by npm run gen:screenshots from the specs in scripts/content/specs.mjs, as light/dark SVG pairs:

scripts/content/specs.mjs
'bpp/sales/credit-note': {
entity: 'Credit Note',
screens: [
{
template: 'form', // form | list | dashboard | login | report | dialog
caption: 'The Credit Note screen.',
alt: 'Credit Note screen with the source invoice selected.',
mock: {
fields: [
{ label: 'Credit Note No.', value: 'AUTO', disabled: true },
{ label: 'Against Invoice', value: 'INV/2026/00881', type: 'select', required: true },
],
},
},
],
},

Writing alt text for a screenshot

AspectPoorGood
Text"Screenshot of the Credit Note screen""Credit Note screen with invoice INV/2026/00881 selected and two lines being reversed"
WhySays it is a screenshot — which the reader already knowsSays what is in it, so someone who cannot see it still follows the procedure

A section is one entry in a product’s nav array:

src/config/projects.ts
{
label: 'Inventory',
icon: 'layers', // from src/components/ui/Icon.astro
index: 'bpp/inventory', // the overview page's content id
summary: 'Stock levels, movements and adjustments.',
collapsed: false,
items: [
{ label: 'Stock Summary', slug: 'bpp/inventory/stock-summary', summary: 'Quantity on hand by product and location.' },
{ label: 'Stock Adjustment', slug: 'bpp/inventory/adjustment', summary: 'Correct a discrepancy found at stock take.' },
],
},

Then create the overview page at src/content/docs/bpp/inventory/index.mdx. It needs almost nothing, because <SectionIndex /> builds the card list from the config:

src/content/docs/bpp/inventory/index.mdx
---
title: Inventory
description: Stock levels, movements and adjustments.
---
The inventory module tracks what you hold, where it is, and how it has moved.
<SectionIndex />

Or scaffold the whole section — overview page and topic pages — with:

Terminal window
npm run gen:content

It writes any page in the navigation that does not have a file yet and leaves existing files alone.

See the README section “Adding a fifth product” for the full walkthrough. In summary:

Add the product to the registry

Append one object to projects in src/config/projects.ts with its id, name, basePath, accent, version and nav.

Scaffold the content

npm run gen:content creates every page the navigation declares.

Generate the screenshots

npm run gen:screenshots creates light/dark mocks at the paths those pages reference.

Write the content

Replace the scaffolded prose with the real thing, page by page.

Day-to-day
npm run dev # http://localhost:4321, hot reloads on save
npm run build # production build + Pagefind search index
npm run preview # serve the build — the only way to test search
npm run check # TypeScript and Astro diagnostics
House style
FieldDescriptionNotes
UI labelsBold, exactly as on screen.Write: Click **Save** (the asterisks are the Markdown)
Menu pathsUse <NavPath>, not prose.Not "go to Sales then Transactions"
Values and codesInline code.`SO/2026/00142`
KeyboardUse <KeyboardShortcut>.Not hand-written bold
VoiceSecond person, present tense, active."Click Save", not "Save should be clicked"
SeverityMatch the callout to the consequence.Danger is for data loss only
HeadingsSentence case. Never skip a level.h2 → h3, never h2 → h4

House style