# Using Vue in Markdown In VitePress, each Markdown file is compiled into HTML and then processed as a [Vue Single-File Component](https://vuejs.org/guide/scaling-up/sfc.html). 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 ` ## Markdown Content The count is: {{ count }} ``` You also have access to VitePress' runtime APIs such as the [`useData` helper](/reference/runtime-api#usedata), which provides access to current page's metadata: **Input** ```html
{{ page }}
``` **Output** ```json { "path": "/using-vue.html", "title": "Using Vue in Markdown", "frontmatter": {}, ... } ``` ## Using Components You can import and use Vue components directly in Markdown files. ### Importing in Markdown If a component is only used by a few pages, it's recommended to explicitly import them where they are used. This allows them to be properly code-split and only loaded when the relevant pages are shown: ```md # Docs This is a .md using a custom component ## More docs ... ``` ### Registering Components Globally If a component is going to be used on most of the pages, they can be registered globally by customizing the Vue app instance. See relevant section in [Extending Default Theme](/guide/extending-default-theme#registering-global-components) for an example. ::: warning IMPORTANT Make sure a custom component's name either contains a hyphen or is in PascalCase. Otherwise, it will be treated as an inline element and wrapped inside a `

` tag, which will lead to hydration mismatch because `

` does not allow block elements to be placed inside it. ::: ### Using Components In Headers You can use Vue components in the headers, but note the difference between the following syntaxes: | Markdown | Output HTML | Parsed Header | | ------------------------------------------------------- | ----------------------------------------- | ------------- | |

 # text <Tag/> 
| `

text

` | `text` | |
 # text \`<Tag/>\` 
| `

text <Tag/>

` | `text ` | The HTML wrapped by `` 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). ::: ## Escaping You can escape Vue interpolations by wrapping them in a `` or other elements with the `v-pre` directive: **Input** ```md This {{ will be displayed as-is }} ``` **Output**

This {{ will be displayed as-is }}

Alternatively, you can wrap the entire paragraph in a `v-pre` custom container: ```md ::: v-pre {{ This will be displayed as-is }}` ::: ``` **Output**
::: v-pre {{ This will be displayed as-is }} :::
## Unescape in Code Blocks By default, all fenced code blocks are automatically wrapped with `v-pre`, so no Vue syntax will be processd inside. To enable Vue-style interpolation inside fences, you can append the language with the `-vue` suffix, e.g. `js-vue`: **Input** ````md ```js-vue Hello {{ 1 + 1 }} ``` ```` **Output** ```js-vue Hello {{ 1 + 1 }} ``` ## 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 ``` ## 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](/reference/site-config#postrender). ::: details <<< @/components/ModalDemo.vue ::: ```md
// ...
```