Skip to main content

Markdown Extensions

VitePress extends standard Markdown with powerful features powered by markdown-it. These extensions enable rich documentation with minimal effort.

Syntax Highlighting

VitePress uses Shiki for syntax highlighting with accurate, beautiful code blocks that support hundreds of languages.
1

Specify Language

Add the language identifier after the opening code fence:
```typescript
interface User {
  id: number
  name: string
}
```
2

Configure Theme

Customize syntax highlighting in your config:
// .vitepress/config.ts
export default {
  markdown: {
    theme: 'github-dark'
    // Or dual themes
    theme: { 
      light: 'github-light', 
      dark: 'github-dark' 
    }
  }
}
3

Add Language Aliases

Create custom language aliases:
export default {
  markdown: {
    languageAlias: {
      'my_lang': 'python'
    }
  }
}

Line Highlighting

Highlight specific lines to draw attention to important code:
```js{4}
export default {
  data () {
    return {
      msg: 'Highlighted!'
    }
  }
}
```

Code Annotations

VitePress supports special comments for focused lines, diffs, and error highlighting:
export default {
  data () {
    return {
      msg: 'Focused!'
    }
  }
}
These transformers are implemented via Shiki’s transformer API. See src/node/markdown/plugins/highlight.ts:80-96 for the implementation.

Line Numbers

Enable line numbers globally or per code block:
// .vitepress/config.ts
export default {
  markdown: {
    lineNumbers: true
  }
}
Override per block with :line-numbers or :no-line-numbers:
```ts:line-numbers=2 {1}
// line-numbers start from 2
const line3 = 'This is line 3'
const line4 = 'This is line 4'
```

Custom Containers

Custom containers provide callout-style blocks for tips, warnings, and more:
::: info
This is an info box.
:::

::: tip
This is a tip.
:::

::: warning
This is a warning.
:::

::: danger
This is a dangerous warning.
:::

::: details
This is a collapsible details block.
:::
Container implementation is in src/node/markdown/plugins/containers.ts:8-27. The plugin uses markdown-it-container to create custom blocks.

GitHub-Flavored Alerts

VitePress supports GitHub-style alerts that render as callouts:
> [!NOTE]
> Highlights information that users should take into account.

> [!TIP]
> Optional information to help a user be more successful.

> [!IMPORTANT]
> Crucial information necessary for users to succeed.

> [!WARNING]
> Critical content demanding immediate attention.

> [!CAUTION]
> Negative potential consequences of an action.

Code Groups

Group related code blocks with tabs for better organization:
::: code-group

```js [config.js]
const config = {
  theme: 'default'
}

export default config
```

```ts [config.ts]
import type { UserConfig } from 'vitepress'

const config: UserConfig = {
  theme: 'default'
}

export default config
```

:::

Import Code Snippets

Import code from external files using the <<< syntax:
1

Basic Import

<<< @/snippets/example.js
The @ symbol maps to your source directory.
2

With Line Highlighting

<<< @/snippets/example.js{2}
3

Region Import

Import only a specific region marked with comments:
<<< @/snippets/example.js#snippet{1}
In your source file:
// #region snippet
export function demo() {
  return 'Hello'
}
// #endregion snippet
4

Specify Language

<<< @/snippets/example.cs{c#}
<<< @/snippets/example.cs{1,2,4-6 c#:line-numbers}
Snippet plugin implementation: src/node/markdown/plugins/snippet.ts:122-216

Markdown File Inclusion

Include markdown content from other files:
# Documentation

## Basics

<!--@include: ./parts/basics.md-->
You can also include specific line ranges or regions:
<!--@include: ./parts/basics.md{3,}-->
<!--@include: ./parts/basics.md#region-name-->

Header Anchors

Headers automatically get anchor links for navigation:

Custom Anchors

# Using custom anchors {#my-anchor}
This allows linking to #my-anchor instead of the auto-generated slug.

Configuration

// .vitepress/config.ts
import markdownItAnchor from 'markdown-it-anchor'

export default {
  markdown: {
    anchor: {
      permalink: markdownItAnchor.permalink.headerLink()
    }
  }
}
Internal links are converted to router links for SPA navigation:
[Home](/) <!-- root index.md -->
[Getting Started](/quickstart) <!-- can omit .md -->
[API Reference](../api/index.html) <!-- or use .html -->
External links automatically get target="_blank" rel="noreferrer":
[VitePress on GitHub](https://github.com/vuejs/vitepress)

Tables

GitHub-flavored Markdown tables with alignment support:
| Feature       | Supported     | Status |
| ------------- | :-----------: | -----: |
| Syntax        | Highlighting  | Active |
| Custom        | Containers    | Active |
| Vue           | Components    | Active |

Emoji

Emoji shortcuts are supported out of the box:
:tada: :rocket: :100:
See the full emoji list.

Table of Contents

Generate a table of contents from headers:
[[toc]]
Configure TOC depth:
// .vitepress/config.ts
export default {
  markdown: {
    toc: { 
      level: [2, 3] 
    }
  }
}

Math Equations

Enable LaTeX math support with markdown-it-mathjax3:
1

Install Package

npm add -D markdown-it-mathjax3@^4
2

Enable in Config

// .vitepress/config.ts
export default {
  markdown: {
    math: true
  }
}
3

Use in Markdown

When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$:
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$

Image Lazy Loading

Enable lazy loading for images:
// .vitepress/config.ts
export default {
  markdown: {
    image: {
      lazyLoading: true
    }
  }
}

Advanced Configuration

Customize the markdown-it instance with plugins:
// .vitepress/config.ts
import { defineConfig } from 'vitepress'
import markdownItFoo from 'markdown-it-foo'

export default defineConfig({
  markdown: {
    config: (md) => {
      md.use(markdownItFoo)
    }
  }
})
The markdown renderer is created in src/node/markdown/markdown.ts:243-400. Custom plugins are applied after built-in VitePress plugins.

Vue Components in Markdown

Use Vue components directly in markdown files:
<script setup>
import CustomComponent from './CustomComponent.vue'
</script>

# My Page

<CustomComponent :count="5" />

The raw Container

Prevent style conflicts when documenting component libraries:
::: raw
Wraps content in a `<div class="vp-raw">`
:::
For style isolation, install PostCSS:
npm add -D postcss
Create docs/postcss.config.mjs:
import { postcssIsolateStyles } from 'vitepress'

export default {
  plugins: [postcssIsolateStyles()]
}

Build docs developers (and LLMs) love