Markdown
Make sure you already know Markdown well before reading this section. If not, please learn some Markdown tutorials first.
Syntax Extensions
The Markdown content in VuePress will be parsed by markdown-it, which supports syntax extensions via markdown-it plugins.
This section will introduce built-in Markdown syntax extensions of VuePress.
You can also configure those built-in extensions, load more markdown-it plugins and implement your own extensions via markdown option and extendsMarkdown option.
Embedded
Embedded by markdown-it:
- Tables (GFM)
- Strikethrough (GFM)
Header Anchors
You might have noticed that, a #
anchor is displayed when you hover the mouse on the headers of each section. By clicking the #
anchor, you can jump to the section directly.
Tips
This header anchors extension is supported by markdown-it-anchor.
Config reference: markdown.anchor
Links
When using Markdown link syntax, VuePress will implement some conversions for you.
Take our documentation source files as an example:
└─ docs
├─ guide
│ ├─ getting-started.md
│ ├─ introduction.md
│ └─ markdown.md # <- Here we are
├─ reference
│ └─ config.md
└─ README.md
Raw Markdown
<!-- relative path -->
[Home](../README.md)
[Config Reference](../reference/config.md)
[Getting Started](./getting-started.md)
<!-- absolute path -->
[Guide > Introduction](/guide/introduction.md)
[Config Reference > markdown.links](/reference/config.md#links)
<!-- URL -->
[GitHub](https://github.com)
Converted to
<template>
<RouteLink to="/">Home</RouteLink>
<RouteLink to="/reference/config.html">Config Reference</RouteLink>
<RouteLink to="/guide/getting-started.html">Getting Started</RouteLink>
<RouteLink to="/guide/introduction.html">Guide > Introduction</RouteLink>
<RouteLink to="/reference/config.html#links">
Config Reference > markdown.links
</RouteLink>
<a href="https://github.com" target="_blank" rel="noopener noreferrer">
GitHub
</a>
</template>
Rendered as
Home
Config Reference
Getting Started
Guide > Introduction
Config Reference > markdown.links
GitHub
Explanation
- Internal links will be converted to RouteLink for SPA navigation.
- Internal links to
.md
files will be converted to the page route path, and both absolute path and relative path are supported. - External links will get
target="_blank" rel="noopener noreferrer"
attrs.
Suggestion
Try to use relative paths instead of absolute paths for internal links to markdown files.
- Relative paths are a valid links to the target files, and they can navigate correctly when browsing the source files in your editor or repository.
- Relative paths are consistent in different locales, so you don't need to change the locale path when translating your content.
Emoji 🎉
You can add emoji to your Markdown content by typing :EMOJICODE:
.
For a full list of available emoji and codes, check out emoji-cheat-sheet.
Input
VuePress 2 is out :tada: !
Output
VuePress 2 is out 🎉 !
Table of Contents
If you want to put the table of contents (TOC) of your current page inside your Markdown content, you can use the [[toc]]
syntax.
Input
[[toc]]
Output
The headers in TOC will link to the corresponding header anchors, so TOC won't work well if you disable header anchors.
Code Blocks
Following code blocks extensions are implemented during markdown parsing in Node side. That means, the code blocks won't be processed in client side.
With [@vuepress/plugin-prismjs][prismjs] and [@vuepress/plugin-shiki][shiki], you can highlight code blocks with Prism or Shiki.
Code Title
You can specify the title of the code block by adding a title
key-value mark in your fenced code blocks.
Input
```ts title=".vuepress/config.ts"
import { defaultTheme } from '@vuepress/theme-default'
import { defineUserConfig } from 'vuepress'
export default defineUserConfig({
title: 'Hello, VuePress',
theme: defaultTheme({
logo: 'https://vuejs.org/images/logo.png',
}),
})
```
Output
import { defaultTheme } from '@vuepress/theme-default'
import { defineUserConfig } from 'vuepress'
export default defineUserConfig({
title: 'Hello, VuePress',
theme: defaultTheme({
logo: 'https://vuejs.org/images/logo.png',
}),
})
Tips
Code title is supported by highlight plugins by default. It can be used in combination with the other marks below. Please leave a space between them.
Line Highlighting
You can highlight specified lines of your code blocks by adding line ranges mark in your fenced code blocks.
Input
```ts{1,7-9}
import { defaultTheme } from '@vuepress/theme-default'
import { defineUserConfig } from 'vuepress'
export default defineUserConfig({
title: 'Hello, VuePress',
theme: defaultTheme({
logo: 'https://vuejs.org/images/logo.png',
}),
})
```
Output
import { defaultTheme } from '@vuepress/theme-default'
import { defineUserConfig } from 'vuepress'
export default defineUserConfig({
title: 'Hello, VuePress',
theme: defaultTheme({
logo: 'https://vuejs.org/images/logo.png',
}),
})
Examples for line ranges mark:
- Line ranges:
{5-8}
- Multiple single lines:
{4,7,9}
- Combined:
{4,7-13,16,23-27,40}
Tips
Line highlighting extension is supported by highlighter plugins.
Config reference: prism line highlighting and shiki highlighting.
Line Numbers
You must have noticed that the number of lines is displayed on the left side of code blocks.
You can add :line-numbers
/ :no-line-numbers
mark in your fenced code blocks to override the value set in config.
Input
```ts
// line-numbers is enabled by default
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:no-line-numbers
// line-numbers is disabled
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
Output
// line-numbers is enabled by default
const line2 = 'This is line 2'
const line3 = 'This is line 3'
// line-numbers is disabled
const line2 = 'This is line 2'
const line3 = 'This is line 3'
Tips
Line numbers extension is supported by highlighter plugins.
Config reference: prism line numbers and shiki line numbers.
Wrap with v-pre
As template syntax is allowed in Markdown, it would also work in code blocks, too.
To avoid your code blocks being compiled by Vue, VuePress will add v-pre directive to your code blocks by default, which can be disabled in config.
You can add :v-pre
/ :no-v-pre
mark in your fenced code blocks to override the value set in config.
Warning
The template syntax characters, for example, the "Mustache" syntax (double curly braces) might be parsed by the syntax highlighter. Thus, as the following example, :no-v-pre
might not work well in some languages.
If you want to make Vue syntax work in those languages anyway, try to disable the default syntax highlighting and implement your own syntax highlighting in client side.
Input
```md
<!-- This will be kept as is by default -->
1 + 2 + 3 = {{ 1 + 2 + 3 }}
```
```md:no-v-pre
<!-- This will be compiled by Vue -->
1 + 2 + 3 = {{ 1 + 2 + 3 }}
```
```js:no-v-pre
// This won't be compiled correctly because of js syntax highlighting
const onePlusTwoPlusThree = {{ 1 + 2 + 3 }}
```
Output
<!-- This will be kept as is -->
1 + 2 + 3 = {{ 1 + 2 + 3 }}
<!-- This will be compiled by Vue -->
1 + 2 + 3 = 6
// This won't be compiled correctly because of js syntax highlighting
const onePlusTwoPlusThree = {{ 1 + 2 + 3 }}
Import Code Blocks
You can import code blocks from files with following syntax:
<!-- minimal syntax -->
@[code](../foo.js)
If you want to partially import the file:
<!-- partial import, from line 1 to line 10 -->
@[code{1-10}](../foo.js)
The code language is inferred from the file extension, while it is recommended to specify it explicitly:
<!-- specify the code language -->
@[code js](../foo.js)
In fact, the second part inside the []
will be treated as the mark of the code fence, so it supports all the syntax mentioned in the above Code Blocks section:
<!-- line highlighting -->
@[code js{2,4-5}](../foo.js)
Here is a complex example:
- import line 3 to line 10 of the
'../foo.js'
file - specify the language as
'js'
- highlight line 3 of the imported code, i.e. line 5 of the
'../foo.js'
file - disable line numbers
@[code{3-10} js{3}:no-line-numbers](../foo.js)
Notice that path aliases are not available in import code syntax. You can use following config to handle path alias yourself:
import { getDirname, path } from 'vuepress/utils'
const __dirname = getDirname(import.meta.url)
export default {
markdown: {
importCode: {
handleImportPath: (str) =>
str.replace(/^@src/, path.resolve(__dirname, 'path/to/src')),
},
},
}
<!-- it will be resolved to 'path/to/src/foo.js' -->
@[code](@src/foo.js)
Tips
This import code extension is supported by our built-in plugin.
Config reference: markdown.importCode
Using Vue in Markdown
This section will introduce some basic usage of Vue in Markdown.
Check out Cookbook > Markdown and Vue SFC for more details.
Template Syntax
As we know:
- HTML is allowed in Markdown.
- Vue template syntax is compatible with HTML.
That means, Vue template syntax is allowed in Markdown.
Input
One plus one equals: {{ 1 + 1 }}
<span v-for="i in 3"> span: {{ i }} </span>
Output
One plus one equals: 2
span: 1 span: 2 span: 3
Components
You can use Vue components directly in Markdown.
Input
This is default theme built-in `<Badge />` component <Badge text="demo" />
Output
This is default theme built-in <Badge />
component demo
Tips
Check out the Built-in Components for a full list of built-in components.
Check out the Default Theme > Built-in Components for a full list of default theme built-in components.
Markdown Plugins
You can explore more markdown plugins at VuePress Marketplace.
Cautions
Non-Standard HTML Tags
Non-standard HTML tags would not be recognized as native HTML tags by Vue template compiler. Instead, Vue will try to resolve those tags as Vue components, and obviously these components usually don't exist. For example:
- Deprecated HTML tags such as <center> and <font>.
- MathML tags, which might be used by some markdown-it LaTeX plugin.
If you want to use those tags anyway, try either of the following workarounds:
- Adding a v-pre directive to skip the compilation of the element and its children. Notice that the template syntax would also be invalid.
- Using compilerOptions.isCustomElement to tell Vue template compiler not try to resolve them as components.
- For
@bundler-webpack
, set vue.compilerOptions - For
@bundler-vite
, set vuePluginOptions.template.compilerOptions
- For