
Writing with Markdown and MDX
A guide to authoring documents with Fumadocs Markdown and MDX features.
Overview
Fumadocs extends MDX with a set of practical authoring features. This page walks through the default Markdown and MDX behavior provided by Fumadocs UI.
MDX is not the only supported format of Fumadocs. In fact, you can use any renderers such as next-mdx-remote or CMS.
Markdown Basics
Fumadocs uses GFM (GitHub Flavored Markdown), which builds on top of CommonMark. You can review the full format in the GFM Specification.
# Heading
## Heading
### Heading
#### Heading
Hello World, **Bold**, _Italic_, ~~Hidden~~
```js
console.log('Hello World');
```
1. First
2. Second
3. Third
- Item 1
- Item 2
> Quote here

| Table | Description |
| ----- | ----------- |
| Hello | World |Auto Links
Internal links are rendered through next/link, which enables prefetching and avoids a full page reload.
External links automatically receive rel="noreferrer noopener" target="_blank" for security.
[My Link](https://github.github.com/gfm)
This also works: https://github.github.com/gfm.MDX Capabilities
MDX expands Markdown with JSX support. That makes it possible to import components, render them inline inside the document, and even export values when needed.
import { Component } from './component';
<Component name="Hello" />See MDX Syntax if you want the full language details.
Cards
Cards are built in and are especially handy for linking to related pages.
<Cards>
<Card
href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating"
title="Fetching, Caching, and Revalidating"
>
Learn more about caching in Next.js
</Card>
</Cards>Add an Icon
Cards can also render an icon.
import { HomeIcon } from 'lucide-react';
<Cards>
<Card icon={<HomeIcon />} href="/" title="Home">
Go back to home
</Card>
</Cards>Use Cards Without Links
If you only need the visual container, href is optional.
<Cards>
<Card title="Fetching, Caching, and Revalidating">
Learn more about `fetch` in Next.js.
</Card>
</Cards>Fetching, Caching, and Revalidating
Learn more about fetch in Next.js.
Callouts
Callouts are included by default and work well for tips, notices, or warnings.
<Callout>Hello World</Callout>Add a Title
You can give a callout its own heading.
<Callout title="Title">Hello World</Callout>Title
Available Types
Callouts support different variants:
info(default)warnerror
<Callout title="Title" type="error">
Hello World
</Callout>Title
Hello World
Customize Components
See all MDX components and available options.
Headings
Each heading automatically gets an anchor, and invalid characters such as spaces are sanitized. For example, Hello World becomes hello-world.
# Hello `World`TOC Settings
The table of contents is generated from headings, and you can influence how headings appear inside it.
# 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
Use [#slug] when you want to provide your own heading id.
# heading [#my-heading-id]You can combine that with TOC settings as well:
# heading [toc] [#my-heading-id]To link to a specific heading, append the anchor to the URL hash: /page#my-heading-id.
Frontmatter
YAML frontmatter is supported for storing shared page metadata such as the title. Place it at the very top of the document.
---
title: Hello World
---
## TitleFor the list of supported properties, see Page Conventions.
Code Blocks
Syntax highlighting is enabled by default through Rehype Code.
```js
console.log('Hello World');
```You can also give a code block a title.
```js title="My Title"
console.log('Hello World');
```Highlight Lines
Add [!code highlight] when a specific line should stand out.
```tsx
<div>Hello World</div> // [\!code highlight]
<div>Hello World</div>
<div>Goodbye</div>
<div>Hello World</div>
```Highlight Words
To emphasize a single word, add [!code word:<match>].
```js
// [\!code word:config]
const config = {
reactStrictMode: true,
};
```Diffs
```ts
console.log('hewwo'); // [\!code --]
console.log('hello'); // [\!code ++]
```console.log('hewwo');
console.log('hello'); Tab Groups
Code blocks can be combined with the <Tab /> component.
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
<Tabs items={['Tab 1', 'Tab 2']}>
<Tab value='Tab 1'>
```ts
console.log('A');
```
</Tab>
<Tab value='Tab 2'>
```ts
console.log('B');
```
</Tab>
</Tabs>Note that you can add MDX components instead of importing them in MDX files.
console.log('A');console.log('B');Using Typescript Twoslash
Twoslash lets your Typescript examples show hover information and detected type errors.
Not enabled by default. See Twoslash.
Images
All built-in content sources handle images correctly.
They are optimized automatically for next/image.

Optional Features
You can enable extra plugins when your docs need them.
Math Equations
Math expressions can be written with TeX.
```mdx
f(x) = x * e^{2 pi i \xi x}
```f(x) = x * e^{2 pi i \xi x}To enable, see Math Integration.
Package Install
You can also generate install command blocks for JS/Node.js package managers.
```mdx
npm i next -D
```npm i next -DTo enable, see Remark Install.
More Plugins
Browse the list of plugins supported by Fumadocs for the rest.
Author
More Posts

Orelune Tarot Series: The Hanged Man - Pause, Perspective & Conscious Surrender
Discover The Hanged Man tarot card on Orelune, including surrender, perspective, love, career, money, symbolism, yes/no guidance, and practical reading support.


The Origins of Tarot: From Renaissance Cards to Modern Reflection
Learn where tarot really came from, how it evolved beyond a Renaissance card game, and why it became a tool for reflection. See how Orelune continues that tradition with AI-assisted insight.


Theming Fumadocs UI
Configure themes, colors, dark mode, and layout styling in Fumadocs UI.
Newsletter
Join the community
Subscribe to our newsletter for the latest news and updates