# Using Vue in Markdown In VitePress, each markdown file is compiled into HTML and then processed as a Vue Single-File Component. This means you can use any Vue features inside the markdown, including dynamic templating, using Vue components, or arbitrary in-page Vue component logic by adding a `
{{ page }}``` **Output** ```json { "path": "/using-vue.html", "title": "Using Vue in Markdown", "frontmatter": {} } ``` ## Escaping By default, fenced code blocks are automatically wrapped with `v-pre`, unless you have set some language with `-vue` suffix like `js-vue` (in that case you can use Vue-style interpolation inside fences). To display raw mustaches or Vue-specific syntax inside inline code snippets or plain text, you need to wrap a paragraph with the `v-pre` custom container: **Input** ```md ::: v-pre `{{ This will be displayed as-is }}` ::: ``` **Output** ::: v-pre `{{ This will be displayed as-is }}` ::: ## Using Components When you need to have more flexibility, VitePress allows you to extend your authoring toolbox with your own Vue Components. ### Importing components in markdown If your components are going to be used in only a few places, the recommended way to use them is to importing the components in the file where it is used. ```md # Docs This is a .md using a custom component
` tag, which will lead to hydration mismatch because `
` does not allow block elements to be placed inside it.
:::
### Using Components In Headers
# text <Tag/>
| ` # text \`<Tag/>\`
| `<Tag/>
` will be displayed as-is; only the HTML that is **not** wrapped will be parsed by Vue.
::: tip
The output HTML is accomplished by [markdown-it](https://github.com/markdown-it/markdown-it), while the parsed headers are handled by VitePress (and used for both the sidebar and document title).
:::
## Using CSS Pre-processors
VitePress has [built-in support](https://vitejs.dev/guide/features.html#css-pre-processors) for CSS pre-processors: `.scss`, `.sass`, `.less`, `.styl` and `.stylus` files. There is no need to install Vite-specific plugins for them, but the corresponding pre-processor itself must be installed:
```
# .scss and .sass
npm install -D sass
# .less
npm install -D less
# .styl and .stylus
npm install -D stylus
```
Then you can use the following in Markdown and theme components:
```vue
```
## Script & Style Hoisting
Sometimes you may need to apply some JavaScript or CSS only to the current page. In those cases, you can directly write root-level `
## Built-In Components
VitePress provides Built-In Vue Components like `ClientOnly`, check out the [Global Component Guide](/api/) for more information.
**Also see:**
- [Using Components In Headers](#using-components-in-headers)
## Browser API Access Restrictions
Because VitePress applications are server-rendered in Node.js when generating static builds, any Vue usage must conform to the [universal code requirements](https://vuejs.org/guide/scaling-up/ssr.html). In short, make sure to only access Browser / DOM APIs in `beforeMount` or `mounted` hooks.
If you are using or demoing components that are not SSR-friendly (for example, contain custom directives), you can wrap them inside the built-in `` component:
```md
```
Note this does not fix components or libraries that access Browser APIs **on import**. To use code that assumes a browser environment on import, you need to dynamically import them in proper lifecycle hooks:
```vue
```
If your module `export default` a Vue component, you can register it dynamically:
```vue
```
**Also see:**
- [Vue.js > Dynamic Components](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components)
## Using Teleports
Vitepress currently has SSG support for teleports to body only. For other targets, you can wrap them inside the built-in `` component or inject the teleport markup into the correct location in your final page HTML through [`postRender` hook](../config/app-config#postrender).
::: details
<<< @/components/ModalDemo.vue
:::
```md
// ...
```