Skip to Content
Fumadocs

Markdown

How to write documents

Introduction

Fumadocs provides many useful extensions to MDX, a markup language. Here is a brief introduction to the default MDX syntax of Fumadocs.

MDX is not the only supported format of Fumadocs. In fact, you can use any renderer such as headless CMS.

See Custom Content Source for details.

MDX

We recommend MDX, a superset of Markdown with JSX syntax. It allows you to import components, and use them in the document, or even writing JavaScript.

See:

import { Component } from './component';

<Component name="Hello" />

## Heading

### Heading

#### Heading

Hello World, **Bold**, _Italic_, ~~Hidden~~

1. First
2. Second
3. Third

- Item 1
- Item 2

> Quote here

![alt](/image.png)

| Table | Description |
| ----- | ----------- |
| Hello | World       |

Frontmatter

Fumadocs support YAML-based frontmatter by default, title represents the page title (h1) in Fumadocs UI.

---
title: This is a document
---

...

For this reason, h1 title (# Heading) is usually unused when writing Markdown/MDX unless you have custom logic for page title rendering.

In Fumadocs MDX

You can use the schema option to add frontmatter properties.

Internal links use the <Link /> component of your React framework to allow prefetching and avoid hard-reload.

External links will get the default rel="noreferrer noopener" target="_blank" attributes for security.

[My Link](https://github.github.com/gfm)

This also works: https://github.github.com/gfm.

Cards

Useful for adding links.

import { HomeIcon } from 'lucide-react';

<Cards>
  <Card href="/docs" title="Documentation">
    Browse the full documentation.
  </Card>
  <Card title="href is optional">Cards can hold plain content too.</Card>
  <Card icon={<HomeIcon />} href="/" title="Home">
    You can include icons too.
  </Card>
</Cards>

Documentation

Browse the full documentation.

href is optional

Cards can hold plain content too.

Home

You can include icons too.

"Further Reading" Section

You can do something like:

page.tsx
import { getPageTreePeers } from 'fumadocs-core/page-tree';
import { source } from '@/lib/source';

<Cards>
  {getPageTreePeers(source.getPageTree(), '/docs/my-page').map((peer) => (
    <Card key={peer.url} title={peer.name} href={peer.url}>
      {peer.description}
    </Card>
  ))}
</Cards>;

This will show the other pages in the same folder as cards.

Callouts

Useful for adding tips/warnings, it is included by default. You can specify the type of callout:

  • info (default)
  • warn/warning
  • error
  • success
  • idea
<Callout>Hello World</Callout>

<Callout title="Title" type="warn">
  Hello World
</Callout>

<Callout title="Title" type="error">
  Hello World
</Callout>

<Callout title="Title" type="idea">
  Hello World
</Callout>
Hello World

Title

Hello World

Title

Hello World

Title

Hello World

Headings

An anchor is automatically applied to each heading, it sanitizes invalid characters like spaces. (e.g. Hello World to hello-world)

# Hello `World`

TOC Settings

The table of contents (TOC) will be generated based on headings, you can also customize the effects of headings:

# Heading [!toc]

This heading will be hidden from TOC.

# Another Heading [toc]

This heading will **only** be visible in TOC, you can use it to add additional TOC items.
Like headings rendered in a React component:

<MyComp />

Custom Anchor

You can add [#slug] to customize heading anchors.

# heading [#my-heading-id]

You can also chain it with TOC settings like:

# heading [toc] [#my-heading-id]

To link people to a specific heading, add the heading id to hash fragment: /page#my-heading-id.

Codeblock

Syntax Highlighting is supported by default using Rehype Code.

```js
console.log('Hello World');
```

```js title="My Title"
console.log('Hello World');
```

Line Numbers

Show line numbers, it also works with Twoslash and other transformers.

```ts twoslash lineNumbers
const a = 'Hello World';
//    ^?
console.log(a); 
```

You can set the initial value of line numbers.

```js lineNumbers=4
function main() {
  console.log('starts from 4');

  return 0;
}
```

Shiki Transformers

We support some of the Shiki Transformers, allowing you to highlight/style specific lines.

```tsx
// highlight a line
<div>Hello World</div> // [!code highlight]

// highlight a word
// [!code word:Fumadocs]
<div>Fumadocs</div>

// diff styles
console.log('hewwo'); // [!code --]
console.log('hello'); // [!code ++]

// focus
return new ResizeObserver(() => {}) // [!code focus]
```

Tab Groups

```ts tab="Tab 1"
console.log('A');
```

```ts tab="Tab 2"
console.log('B');
```
console.log('A');

To add a persist ID, define tab-group at the first codeblock:

```ts tab="Tab 1" tab-group="my-custom-group"
console.log('A');
```

```ts tab="Tab 2"
console.log('B');
```
console.log('A');

Another group:

console.log('A');

MDX in Tab Groups

Tab groups come from the remarkCodeTab remark plugin, which Fumadocs MDX enables by default. To use MDX in tab values, enable its parseMdx option:

source.config.ts
import { defineConfig } from 'fumadocs-mdx/config';

export default defineConfig({
  mdxOptions: {
    remarkCodeTabOptions: {
      parseMdx: true, 
    },
  },
});
```ts tab="<Building /> Tab 1"
console.log('A');
```

```ts tab="<Rocket /> Tab 2"
console.log('B');
```
console.log('A');

Include

Reference another file (can also be a Markdown/MDX document). Fumadocs MDX always enables it with Remark Include. Specify the target file path in <include> tag (relative to the MDX file itself).

page.mdx
<include>./another.mdx</include>

See other usages of include.

Show

Show content on a condition. Fumadocs MDX and @fumadocs/astro always enable it with Remark Show. when takes a JS expression:

[framework]/deploy.mdx
Deploy your {props.framework} site.

<show when={props.framework === 'astro'}>
## Adapters

Add an adapter to your Astro config.

</show>

A condition is decided at build time when it only reads:

  • the path params of the page, as props.
  • the env vars that bundlers inline: NEXT_PUBLIC_*, VITE_* and PUBLIC_*.
  • the define option of Remark Show.

Statically generated properties, like the table of contents and search index, only include the branches that show. Other conditions are checked when rendering.

NPM Commands

Useful for generating commands for installing packages with different package managers.

```npm
npm i next -D
```

See remark-npm for details.

Steps

Useful for denoting steps for guides, see remark-steps for enable & configure.

### Installation [step]

### Write Code [step]

### Deploy [step]

Installation

Write Code

Deploy

Other Components

You can configure & use the built-in components in your MDX document, such as Tabs, Accordions and Zoomable Image.

Additional Features

You may be interested:

How is this guide?

Last updated on