# Using Vue in Markdown
# Browser API Access Restrictions
Because VuePress applications are server-rendered in Node.js when generating static builds, any Vue usage must conform to the universal code requirements (opens new window). 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 <ClientOnly>
component:
<ClientOnly>
<NonSSRFriendlyComponent/>
</ClientOnly>
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:
<script>
export default {
mounted () {
import('./lib-that-access-window-on-import').then(module => {
// use code
})
}
}
</script>
If your module export default
a Vue component, you can register it dynamically:
<template>
<component v-if="dynamicComponent" :is="dynamicComponent"></component>
</template>
<script>
export default {
data() {
return {
dynamicComponent: null
}
},
mounted () {
import('./lib-that-access-window-on-import').then(module => {
this.dynamicComponent = module.default
})
}
}
</script>
Also see:
# Templating
# Interpolation
Each Markdown file is first compiled into HTML and then passed on as a Vue component to vue-loader
. This means you can use Vue-style interpolation in text:
Input
{{ 1 + 1 }}
Output
2
# Directives
Directives also work:
Input
<span v-for="i in 3">{{ i }} </span>
Output
1 2 3
# Access to Site & Page Data
The compiled component does not have any private data but does have access to the site metadata and computed properties. For example:
Input
{{ $page }}
Output
{
"path": "/using-vue.html",
"title": "Using Vue in Markdown",
"frontmatter": {}
}
# Escaping
By default, fenced code blocks are automatically wrapped with v-pre
. 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
::: v-pre
`{{ This will be displayed as-is }}`
:::
Output
{{ This will be displayed as-is }}
# Using Components
Any *.vue
files found in .vuepress/components
are automatically registered as global (opens new window), async (opens new window) components. For example:
.
└─ .vuepress
└─ components
├─ demo-1.vue
├─ OtherComponent.vue
└─ Foo
└─ Bar.vue
Inside any Markdown file you can then directly use the components (names are inferred from filenames):
<demo-1/>
<OtherComponent/>
<Foo-Bar/>
Hello this is <demo-1>
This is another component
Hello this is <Foo-Bar>
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 <p>
tag, which will lead to hydration mismatch because <p>
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 |
---|---|---|
| <h1>text <Tag/></h1> | text |
| <h1>text <code><Tag/></code></h1> | text <Tag/> |
The HTML wrapped by <code>
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 (opens new window), while the parsed headers are handled by VuePress (and used for both the sidebar and document title).
# Using Pre-processors
VuePress has built-in webpack support for the following pre-processors: sass
, scss
, less
, stylus
and pug
. All you need to do is installing the corresponding dependencies. For example, to enable sass
:
yarn add -D sass-loader node-sass
Now you can use the following in Markdown and theme components:
<style lang="sass">
.title
font-size: 20px
</style>
Using <template lang="pug">
requires installing pug
and pug-plain-loader
:
yarn add -D pug pug-plain-loader
TIP
If you are a Stylus user, you don’t need to install stylus
and stylus-loader
in your project; VuePress uses Stylus internally.
For pre-processors that do not have built-in webpack config support, you will need to extend the internal webpack config and install the necessary dependencies.
# 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 <script>
or <style>
blocks in the Markdown file. These will be hoisted out of the compiled HTML and used as the <script>
and <style>
blocks for the resulting Vue single-file component:
# Built-In Components
# OutboundLink stable
The indicator (opens new window) is used to denote external links. In VuePress, this component has been followed by every external link.
# ClientOnly stable
See Browser API Access Restrictions.
# Content
Props:
pageKey
- string, page's hash key, defaults to current page’s key.slotKey
- string, key of Markdown slot. Defaults to default slot.
Usage:
Specify a specific slot for a specific page (.md) for rendering. This is useful when using a Custom Layout or Writing a theme:
<Content/>
Also see:
# Badge beta default theme
Props:
text
- stringtype
- string, optional value:"tip"|"warning"|"error"
, defaults to"tip"
.vertical
- string, optional value:"top"|"middle"
, defaults to"top"
.
Usage:
You can use this component in a header to add some status for an API:
### Badge <Badge text="beta" type="warning"/> <Badge text="default theme"/>
Also see: