Docusaurus Markdown & MDX Formatting Guidelines
These guidelines are tailored for a documentation site where most content consists of code blocks and quick-reference snippets. All recommendations are based on the official Docusaurus documentation and established best practices.
- Code blocks: Code blocks
- Tabs: Tabs
- Admonitions: Admonitions
- Links: Markdown links
- Assets (images/files/SVG): Assets
- Headings & TOC: Headings and TOC
- Prism config (syntax highlighting): Theme configuration → prism
- Diagrams: Mermaid diagrams
- Math: Math equations (KaTeX)
- MDX & React components: MDX and React
1. Choose .md vs .mdx (When to Use MDX)
- Use the
.mdxextension whenever you need any of the following features: Tabs, Admonitions, Mermaid diagrams, embedded React components, or advanced code features like<CodeBlock>and importing code as raw text. See MDX & React. - MDX is strict. If Prettier causes formatting issues, you can add a
/* prettier-ignore */comment above the problematic block or exclude*.mdxfiles from Prettier formatting.
2. Headings & Table of Contents
- Each page should have only one H1 heading (
#), which serves as the document title. Main sections should begin with an H2 heading (##). - Each heading automatically gets an ID based on its text. For stable anchor links, you should set an explicit ID:
### Installation Steps {#installation-steps}
You can then link to it using[see here](#installation-steps).
Source: Headings & TOC - The Table of Contents (TOC) defaults to including headings from
h2toh3. You can adjust this range on a per-page basis using front matter or globally in the theme configuration.
---
toc_min_heading_level: 2
toc_max_heading_level: 5
---
// docusaurus.config.js
export default {
themeConfig: {
tableOfContents: { minHeadingLevel: 2, maxHeadingLevel: 5 },
},
};
References: Headings & TOC, Theme configuration
3. Links & Cross-References
Prefer relative file-path links (including the .md or .mdx extension) when linking between documents. Docusaurus automatically converts these paths into final URL routes, ensuring they remain correct across different versions and locales.
- Examples (from
docs/folder/doc1.mdx):
I am referencing a [document](doc2.mdx).
This one is [in a subfolder](subfolder/doc3.mdx).
This link goes [across folders](../otherFolder/doc4.mdx).
Avoid hard-coded absolute URL paths like /docs/..., as they are not portable. Source: Markdown links
4. Images, Files, and Assets
- Co-locate assets with your Markdown files when it's convenient:
/website/docs/myFeature.mdx
/website/docs/assets/docusaurus-asset-example-banner.png
/website/docs/assets/docusaurus-asset-example.docx
- Images can be embedded using standard Markdown,
require, or animportstatement:

<img
src={require("./assets/docusaurus-asset-example-banner.png").default}
alt="Example banner"
/>
import myImageUrl from "./assets/docusaurus-asset-example-banner.png";
<img src={myImageUrl} alt="Example banner" />;
- Link to downloadable files using standard Markdown syntax:
[Download this docx](./assets/docusaurus-asset-example.docx)
- Absolute paths resolve from your
staticdirectories: - To bypass asset processing and use a raw URL path, prefix it with
pathname:///:

Source: Assets
Note: Some users report issues with reference-style image links. Inline Markdown or JSX forms are the most reliable methods in Docusaurus.
5. Code Blocks — Core Practices
Use fenced code blocks with language tags and enhance them with Docusaurus features.
a) Basic Fenced Blocks
Always specify the language for syntax highlighting.
console.log("Hello, Docusaurus!");
Source: Code blocks
b) Code Titles
Use a title attribute to add a descriptive header, such as a file path.
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}
c) Line Numbering
Add the showLineNumbers attribute to display line numbers.
export default function Example() {
return <div>Hello</div>;
}
d) Line Highlighting
You can highlight specific lines using either metadata in curly braces or "magic comments."
- Metadata Ranges (good for short, stable snippets):
import React from "react";
function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}
return <div>Foo</div>;
}
- Magic Comments (great for snippets that mirror evolving source code):
function doThing(flag) {
if (flag) {
return "highlighted";
}
return "plain";
}
- You can customize magic comments and their styles via the theme configuration and custom CSS:
// docusaurus.config.js
export default {
themeConfig: {
prism: {
magicComments: [
{
className: "theme-code-block-highlighted-line",
line: "highlight-next-line",
block: { start: "highlight-start", end: "highlight-end" },
},
{ className: "code-block-error-line", line: "This will error" },
],
},
},
};
/* custom.css */
:root {
--docusaurus-highlighted-code-line-bg: rgb(72, 77, 91);
}
[data-theme="dark"] {
--docusaurus-highlighted-code-line-bg: rgb(100, 100, 100);
}
.code-block-error-line {
background-color: #ff000020;
border-left: 3px solid #ff000080;
}
References: Code blocks
e) Syntax Highlighting Themes (Prism)
- The default theme is Palenight. You can switch themes and add support for more languages in
docusaurus.config.js.
// docusaurus.config.js
import { prismThemes } from "prism-react-renderer";
export default {
themeConfig: {
prism: {
theme: prismThemes.dracula,
// darkTheme: prismThemes.dracula, // Optional: specify a different theme for dark mode
additionalLanguages: ["powershell", "csharp", "java"],
},
},
};
References: Code blocks, Theme configuration
f) Multi-Language Examples with Tabs
Use Tabs to present code in different languages (e.g., JS/TS) or for different platforms (e.g., macOS/Windows/Linux).
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
<Tabs groupId="operating-systems" defaultValue="mac" queryString="os">
<TabItem value="mac" label="macOS">
```bash
brew install my-tool
```
</TabItem>
<TabItem value="win" label="Windows">
```powershell
choco install my-tool
```
</TabItem>
<TabItem value="linux" label="Linux">
```bash
sudo apt-get install my-tool
```
</TabItem
</Tabs>
References: Tabs
g) Automatic npm/yarn/pnpm Tabs
Use the npm2yarn remark plugin to automatically transform npm install commands into a set of tabs for npm, yarn, and pnpm.
npm install @docusaurus/remark-plugin-npm2yarn
// docusaurus.config.js
remarkPlugins: [
[require("@docusaurus/remark-plugin-npm2yarn"), { sync: true }],
];
Reference: Code blocks → npm2yarn
h) Live, Editable Code Blocks
Install and enable the live code block theme, then use the live language identifier on a code block.
npm install @docusaurus/theme-live-codeblock
function Clock() {
const [date, setDate] = React.useState(new Date());
React.useEffect(() => {
const id = setInterval(() => setDate(new Date()), 1000);
return () => clearInterval(id);
}, []);
return <h2>{date.toLocaleTimeString()}</h2>;
}
Reference: Code blocks → Interactive code editor
i) Import Code from Files (DRY Principle)
Use MDX with the @theme/CodeBlock component and raw-loader to keep documentation in sync with your source code.
npm install --save-dev raw-loader
import CodeBlock from "@theme/CodeBlock";
import ComponentSource from "!!raw-loader!./_my-component.tsx";
<CodeBlock language="tsx" title="/src/components/MyComponent.tsx">
{ComponentSource}
</CodeBlock>
Reference: MDX & React → Importing code snippets
6. Tabs — Conventions and Best Practices
- Default Tab: Add the
defaultprop to aTabItemor set thedefaultValueprop on the parentTabscomponent. - Syncing: Use the same
groupIdto sync the selected tab across multiple tab groups on the same page. - Persist in URL: Add a
queryStringprop toTabsto sync the selection with a URL query parameter. - Performance: For pages with many tabs, use
<Tabs lazy />to render only the active tab's content on the initial page load.
Source: Tabs
7. Admonitions — Callouts for Notes and Warnings
- Use triple-colon syntax with a type:
note,tip,info,warning, ordanger.
:::tip[Quick Tip]
Use line highlighting to draw attention to critical lines in your code snippets.
:::
- Prettier: Keep blank lines before and after admonitions to prevent auto-formatting from breaking the syntax.
- Nesting: You can nest admonitions by adding more colons (
::::). - MDX: Admonitions work in
.mdxfiles, and you can even place other components likeTabsinside them.
Source: Admonitions
8. Diagrams with Mermaid (Optional)
- First, enable the Mermaid theme:
npm install @docusaurus/theme-mermaid
// docusaurus.config.js
export default {
markdown: { mermaid: true },
themes: ["@docusaurus/theme-mermaid"],
};
- Use a fenced code block with the
mermaidlanguage identifier:
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
Source: Diagrams
9. Math Equations with KaTeX (Optional)
- Install and enable the required remark/rehype plugins:
npm install remark-math@6 rehype-katex@7
// docusaurus.config.js
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
export default {
presets: [
[
"@docusaurus/preset-classic",
{ docs: { remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex] } },
],
],
stylesheets: [
{
href: "https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css",
type: "text/css",
integrity:
"sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM",
crossorigin: "anonymous",
},
],
};
- Inline math:
$f(x)=x^2$ - Block math:
$$
I = \int_0^{2\pi} \sin(x)\,dx
$$
Source: Math equations
10. Opinionated Style Guide
- Prefer short, focused snippets. Add a
titlewith the absolute repository path to aid in searching:
title="/app/services/payments/createCharge.ts" - When mirroring real code, use magic comments for highlighting, as they are more maintainable than line numbers.
- Use
showLineNumbersfor snippets longer than 10-15 lines. - For command-line instructions, use
bashorpowershelland enablenpm2yarnfor consistency. - For OS- or language-specific instructions, always use
Tabswith a sharedgroupId. - Use admonitions to highlight important caveats (e.g., "Requires Node 20+", "macOS only", "Experimental feature").
- Add explicit heading IDs (
{#custom-id}) to create stable deep links. - Co-locate assets next to your documents and use standard Markdown image syntax for simplicity.
11. Copy-Paste Snippets
Prism Theme and Additional Languages
// docusaurus.config.js
import { prismThemes } from "prism-react-renderer";
export default {
themeConfig: {
prism: {
theme: prismThemes.dracula,
additionalLanguages: ["powershell", "csharp", "bash"],
},
},
};
Synced Tabs with URL Persistence
<Tabs groupId="os" defaultValue="mac" queryString="os">
<TabItem value="mac" label="macOS" default>
```bash brew install my-tool ```
</TabItem>
<TabItem value="win" label="Windows">
```powershell choco install my-tool ```
</TabItem>
<TabItem value="linux" label="Linux">
```bash sudo apt-get install my-tool ```
</TabItem>
</Tabs>
Admonition with Nested Tabs
:::warning[Breaking Change in v3.0]
The CLI flags have changed. Please use the correct flag for your operating system.
<Tabs groupId="os">
<TabItem value="mac" label="macOS">
Use the `--darwin` flag.
</TabItem>
<TabItem value="win" label="Windows">
Use the `--windows` flag.
</TabItem>
</Tabs>
:::