Docgeni parses Markdown with Marked and enables GFM (GitHub Flavored Markdown) by default. This page covers common standard syntax and Docgeni-specific extensions for writing documentation.
Use # for heading levels 1–6:
markdown# Heading 1 ## Heading 2 ### Heading 3 #### Heading 4 ##### Heading 5 ###### Heading 6
Headings level 1–4 get automatic anchor IDs and appear in the on-page table of contents. IDs are derived from the heading text (lowercased; spaces and punctuation become -).
Use relative paths to link to other pages or assets in the site:
markdown[Getting started](../intro/getting-started) [Navigation & menu](./nav-menu)
Links starting with http:// or https:// open in a new tab (target="_blank"):
markdown[Docgeni on GitHub](https://github.com/docgeni/docgeni)
YAML Front Matter at the top of each file configures page metadata. Separate it from the body with ---:
markdown--- title: Getting started path: getting-started order: 10 hidden: false toc: content --- Body content starts here…
Common fields include title, path, order, hidden, and toc. See Front Matter for the full reference.
Docgeni reads Front Matter at build time for navigation, menus, routes, and titles. Only the body is passed to the Markdown renderer.
GFM table syntax:
markdown| Column A | Column B | | --- | --- | | Cell 1 | Cell 2 | | Cell 3 | Cell 4 |
| Column A | Column B |
|---|---|
| Cell 1 | Cell 2 |
| Cell 3 | Cell 4 |
Fenced code blocks with a language identifier enable highlighting and copy:
markdown```typescript const greeting = 'Hello Docgeni'; console.log(greeting); ```
Rendered:
typescriptconst greeting = 'Hello Docgeni'; console.log(greeting);
The block shows a language label and copy button. Supported languages depend on your Prism setup.
Wrap multiple fenced blocks in a code-group container. Add [Tab label] after the language on each fence:
::: code-group
```bash [npm]
npm install -D @docgeni/cli
```
```bash [yarn]
yarn add -D @docgeni/cli
```
```bash [pnpm]
pnpm add -D @docgeni/cli
```
:::Rendered:
bashnpm install -D @docgeni/cli
bashyarn add -D @docgeni/cli
bashpnpm add -D @docgeni/cli
Internally this becomes <tabs mode="code-group">, same as built-in components.
The <embed> tag inlines another Markdown file relative to the current file:
html<embed src="../../../guides/basic/foo.md"></embed>
Example:
This is foo
You can import line ranges:
html<!-- Full file --> <embed src="../../../guides/basic/foo.md"></embed> <!-- Line 1 only --> <embed src="../../../guides/basic/foo.md#L1"></embed> <!-- Lines 5–10 --> <embed src="../../../guides/basic/foo.md#L5-L10"></embed>
Front Matter in the embedded file is stripped; only the body is rendered.
Besides built-in extensions (embed, code-group, tabs, etc.), configure Marked in .docgenirc.js / .docgenirc.ts:
tsimport { markedEmoji } from 'marked-emoji'; export default { markdown: { config: (marked) => { // Third-party marked extension marked.use( markedEmoji({ emojis: { heart: '❤️', tada: '🎉' }, renderer: (token) => token.emoji, }), ); // Or a custom extension marked.use({ extensions: [ { name: 'callout', level: 'block', start(src) { return src.match(/^:::\s*tip\b/m)?.index; }, tokenizer(src) { const rule = /^:::\s*tip\s*\n([\s\S]*?)\n:::\s*(?:\n|$)/; const match = rule.exec(src); if (!match) return; return { type: 'callout', raw: match[0], text: match[1].trim() }; }, renderer(token) { return `<div class="callout tip">${token.text}</div>\n`; }, }, ], }); }, }, };
Notes:
config runs when Docgeni initializes Marked, after GFM and built-in extensions are registered.marked.use() to add packages from the marked ecosystem or implement Marked extensions (name, level, start, tokenizer, renderer, etc.)..docgeni/components.With marked-emoji configured, :heart: in prose renders as ❤️.