How to Write Docs
Internal guide for the MediFlux documentation team, file structure, frontmatter, components, and writing conventions.
Internal only
This page is not linked in the sidebar or navigation. Share the URL directly with team members: /docs/how-to-write. Do not add this file to any meta.json.
This guide covers everything you need to author, organize, and publish MediFlux documentation. The site is built with Fumadocs + Next.js. Documentation lives under content/docs/. Help & FAQs live under content/help/ with the same folder, meta.json, and MDX component setup.
Quick Reference
File Structure And URLs
All documentation files live in content/docs/. The folder structure determines the URL:
Naming Rules
- Use kebab-case for file and folder names:
create-sale.mdx, notCreateSale.mdx. - Every section folder should have an
index.mdx: this is the landing page for that section (e.g./docs/sales). - Co-locate a
meta.jsoninside each section folder to control sidebar order.
Where To Put A New Page
- Pick the section (e.g.
sales,purchases,introduction). - Create
{section}/{slug}.mdx. - Add the slug (without
.mdx) to{section}/meta.jsonunder"pages". - If you created a new section, also add the folder name to the root
content/docs/meta.json.
Example, adding a page to Sales:
{
"title": "Sales",
"pages": ["index", "create-sale", "returns", "your-new-page"]
}Example, root navigation with section dividers:
{
"title": "MediFlux",
"pages": [
"---Introduction---",
"introduction",
"---Sales---",
"sales"
]
}Strings like "---Introduction---" render as non-clickable section labels in the sidebar.
Help & FAQs
Help articles use the same MDX components and meta.json navigation as docs. They live in content/help/ and map to /help/{section}/{slug}.
Do not put an index.mdx at the help root: /help is the searchable FAQ list. Each section still needs its own index.mdx and meta.json.
Help vs documentation
Keep these as two layers, not two copies of the same page.
Rules:
- Docs own the feature. Help should not retell the full workflow.
- Help owns the stuck moment. Write the question the way a pharmacist would ask it.
- Link, don’t copy. Every Help article should set
relatedto one or more/docs/...URLs. Those render as “Related documentation” under the answer. - Doc-page FAQs stay short. If an accordion answer on a doc grows past a few sentences, move it to Help and link there.
---
title: Why is GST not applying on a sale?
description: Check tax settings, item HSN, and customer GSTIN when GST is missing from a bill.
tags: [sales, gst, billing]
related:
- /docs/sales/add-sale-retail
---- Use
titleanddescriptionthe same way as docs. - Use
tagsinstead oficon. Tags appear as filters on/help. - Use
relatedfor the canonical doc pages. Titles and descriptions are pulled from those pages. - Add the slug to
{section}/meta.json, and add new sections tocontent/help/meta.json. - Search on
/helpmatches title, description, tags, section, and the answer body.
Frontmatter
Every MDX file starts with YAML frontmatter between --- delimiters:
---
title: Create Sale
description: Learn how to create and process a new sale transaction.
icon: Plus
---Supported Fields
Icons
Use any icon name from Lucide Icons in PascalCase:
icon: ShoppingCart # ✓
icon: shopping-cart # ✗ won't renderIcons appear in search results and are auto-filled on <Card> / <WideCard> when you link to a page that has an icon set.
Writing A Doc
Structure
Follow this pattern for most guides:
- Opening paragraph, what the page covers and who it's for (2–4 sentences).
- Prerequisites or context, link to related pages if needed.
- Main sections, use
##for top-level sections (these appear in the table of contents). - Steps or tabs, for procedural or multi-path content.
- Reference tables or code, for API fields, shortcuts, config options.
- Next steps, cards linking to related docs.
Headings
- Use a single
#only if you need an in-page heading: the pagetitlein frontmatter is already rendered as the H1. - Use
##for main sections (shown in TOC). - Use
###inside steps, tabs, or accordions. - Keep heading text short and scannable.
Links
Internal links use root-relative paths:
See [Installation](/docs/introduction/installation) for setup steps.External links open in a new tab automatically. You don't need to add target="_blank".
Text Formatting
**Bold** for UI labels and emphasis.
*Italic* for terms on first use.
`inline code` for keys, commands, and field names.Keyboard shortcuts use the <kbd> HTML tag:
Press F2 to start a new sale.
Lists
Unordered:
- First item
- Second item
- Nested itemOrdered:
1. Step one
2. Step two
3. Step threeStandard Markdown Elements
These work out of the box, no custom components needed.
Tables
Tables are wrapped automatically in a responsive scroll container:
Code Blocks
Use fenced code blocks with an optional language and title:
```typescript title="Example: Create a sale"
const sale = await fetch("/v1/sales", { method: "POST" });
```Features:
- Syntax highlighting for common languages
- Copy button on hover
- Title bar when you add
title="..."after the language
Supported title syntax: ```lang title="My title" or the data-title attribute.
Images
Standard Markdown images get a styled figure with the alt text as caption:
For separate title and description, use the Figure component (see Media).
Components
All components below are registered in lib/mdx-components.tsx and available in every MDX file without importing.
Callout
Highlighted boxes for tips, warnings, and important notes.
Props: type (info | warning | success | danger | note), optional title
<Callout type="info">
MediFlux supports both cloud and on-premise deployments.
</Callout>
<Callout type="warning" title="Important">
Prescription items require pharmacist verification before payment.
</Callout>Shorthand aliases:
<Note>Same as Callout type="info".</Note>
<Warning>Same as Callout type="warning".</Warning>This is a live info callout.
Example warning
This is a live warning callout with a title.
This is a live success callout.
This is a live danger callout.
Example note
This is a live note callout.
Steps
Numbered vertical steps for procedures. Each step can contain headings, paragraphs, code, and callouts.
<Steps> props: optional className
<Step> props: optional title (renders above step body; you can also use ### headings inside)
<Steps>
<Step title="First step">
Body text for step one.
</Step>
<Step>
### Or Use A Heading Inside
Body text for step two.
</Step>
</Steps>Example step one
Steps render with numbered circles and a connecting line.
Example step two
Nest callouts, code blocks, and lists inside steps freely.
Tabs
Switch between alternative content (install methods, languages, auth types).
<Tabs> props: items (tab labels), optional defaultValue, optional className
<Tab> props: value (must match an entry in items), optional label
<Tabs items={["Docker", "Manual"]}>
<Tab value="Docker">
Docker install instructions…
</Tab>
<Tab value="Manual">
Manual install instructions…
</Tab>
</Tabs>Content for tab A.
Cards
Grid of link cards, ideal for section index pages and "Explore" sections.
<Cards> / <CardGroup> props: cols (1 | 2 | 3 | 4, default 2)
<Card> props: title, description, icon, href, optional className
When href points to an internal doc page, title, description, and icon are auto-filled from that page's frontmatter if you omit them.
<Cards cols={2}>
<Card
title="Create Sale"
description="Step-by-step sale workflow."
href="/docs/sales/add-sale-retail"
/>
<Card href="/docs/sales/returned-sales" />
</Cards>Cards example
Grid layout with optional icons and links.
Linked card
Links to the sales section.
Wide Cards
Full-width stacked link rows, good for "Next steps" at the bottom of a page.
<WideCards> props: optional className
<WideCard> props: title, description, icon, href, target, optional className
External URLs open in a new tab automatically. Use target="_blank" to force it on internal links if needed.
<WideCards>
<WideCard href="/docs/introduction/installation" />
<WideCard
title="External link"
description="Opens in a new tab."
href="https://example.com"
icon="ExternalLink"
/>
</WideCards>Wide card example
Full-width card for prominent links.
Accordion
Collapsible sections for FAQ-style or advanced content.
Use <Accordions> as the wrapper and <Accordion> for each item (these names map to the underlying Accordion / AccordionItem components).
<Accordions> props: type (single | multiple, default single)
<Accordion> props: title (required), optional value
<Accordions>
<Accordion title="First question">
Answer content here.
</Accordion>
<Accordion title="Second question">
More answer content.
</Accordion>
</Accordions>Badge
Inline status labels.
Props: variant (default | secondary | destructive | outline)
<Badge>New</Badge>
<Badge variant="secondary">Beta</Badge>
<Badge variant="destructive">Deprecated</Badge>
<Badge variant="outline">Optional</Badge>Examples: New Beta Deprecated Optional
File Tree
Visual folder structure for explaining project layout.
<FileTree> props: optional className
<FileTreeFolder> props: name, optional defaultOpen, children
<FileTreeFile> props: name, optional active
<FileTree>
<FileTreeFolder name="src" defaultOpen>
<FileTreeFile name="index.ts" active />
<FileTreeFile name="utils.ts" />
</FileTreeFolder>
</FileTree>Media
Figure
Image with separate title and description (better than Markdown when you need both).
Props: src, title, optional description, optional alt, optional className
<Figure
src="https://picsum.photos/seed/example/800/400"
title="Example screenshot"
description="Replace with a real product screenshot."
/>YouTube
Props: id or url, optional title, optional description
<YouTube id="dQw4w9WgXcQ" title="Walkthrough" />
<YouTube url="https://www.youtube.com/watch?v=..." title="Walkthrough" />Video
Hosted MP4 or other video URL.
Props: src, optional title, optional description
<Video src="https://example.com/demo.mp4" title="Product demo" />Putting It Together, Checklist
Before opening a PR for a new doc page:
- File is in the correct section folder with kebab-case name
- Frontmatter has
titleanddescription iconis set (PascalCase Lucide name)- Slug added to section
meta.json(unless intentionally hidden like this page) - Opening paragraph explains purpose without repeating the title
##headings structure the page and populate the TOC- Procedures use
<Steps>; alternatives use<Tabs> - Code blocks include
title="..."when the snippet needs context - Internal links use
/docs/...paths - Index/landing pages link to child pages via
<Cards>
Local Development
npm install
npm run devOpen http://localhost:3000/docs/how-to-write to preview this page.
After editing MDX, the dev server hot-reloads. If a new file doesn't appear, restart the dev server once so Fumadocs regenerates the content source.
Adding A New Component
If the team needs a component that doesn't exist yet:
- Create it in
components/mdx/your-component.tsx - Register it in
lib/mdx-components.tsxinsidegetMdxComponents() - Mirror the registration in
mdx-components.tsx(used by the MDX bundler) - Document it on this page with props and a live example
Keep components in components/mdx/ and follow existing patterns (Tailwind classes, cn() utility, client directive only when needed).
Markdown Export
Every public doc page exposes a raw markdown version at {url}.md (e.g. /docs/sales/add-sale-retail.md). This is used by the "Copy markdown" action and LLM integrations. Write content so it reads well in both rendered and plain markdown form.