Vite-Vue-MD: Import .md file as Vue.js Components

This Vite plugin adds support for importing a Markdown file as a Vue component. Works with Vue 2 & 3.

Vue.js Demo Blocks

Render your Vue.js code blocks inline by simply adding demo next to the language name.

For example, when this Markdown file is rendered with this plugin, you'll see a clickable button here:

```vue demo
<script setup>
const clickHandler = () => alert('Clicked!')

    <button @click="clickHandler">
        Click me


npm install -D vite-vue-md


In your vite.config.js file:

  1. Import vite-vue-md and add it to the plugins array.
  2. In your vue() plugin options, add a include option that includes .md files.


  import vue from '@vitejs/plugin-vue'
+ import vueMd from 'vite-vue-md'

  export default {
      plugins: [
          // ...

+             include: [/\.vue$/, /\.md$/] // ← Treat MD files as Vue components

+         vueMd(/* Options */) // ← Compile MD files to Vue components
      // ...

To compile a Vue.js codeblock as a Demo Block, add demo next to the language name:

```vue demo
<script setup>
const clickHandler = () => alert('Clicked!');

    <button @click="clickHandler">
        Click me

Multi-file demos

The entry point for demo blocks must be a Vue.js component. But you can import other code blocks in any language from the same Markdown file.

For non-entry files, set a file name via demo=<file name>. Then import it from the Vue.js demo block via the doc: protocol:

<script setup>
import { clickHandler } from 'doc:click-handler.js'

    <button @click="clicked">
        Click me

Second file:
export const clickHandler = () => alert('Clicked!');

Demo + Code blocks

Since the code blocks are rendered inline, they're replaced by the actual Vue.js component. To show the code block, you can add a onDemo callback to the plugin options:

    onDemo(componentTag, code) {
        // Register the wrapper component
        this.registerComponent('DemoContainer', './DemoContainer.vue')

        // Return a custom HTML string
        return `
            <!-- Inline the component here -->

            <!-- Pass in the code block here -->
            <template #code>
                <template v-pre>${this.escapeHtml(code)}</template>



Type: ReadonlyArray<string | RegExp> | string | RegExp

Files to include from being compiled as Vue files.


Type: ReadonlyArray<string | RegExp> | string | RegExp

Files to exclude from being compiled as Vue files.


Type: markdownIt.Options

MarkdownIt options. See MarkdownIt's documentation for more information.


Type: (md: markdownIt) => void;

Callback to add plugins to MarkdownIt.


Type: string

Default: markdown-body

The class to add to the wrapper element that contains the Markdown page.



    tag: string,
    code: string,
    demos: Map<string, string>
) => string

You can intercept each demo block and return a custom HTML string. This is useful for adding custom styling to demo blocks.

In addition, there are utils exposed in the this context:

  • escapeHtml: Escape HTML code to prevent it from being rendered as HTML.
  • registerComponent: Register a component to be used in the demo block. This is useful for registering components that are imported from other files.

See example above in the Demo Blocks section.


Type: string

File path to a stylesheet to use for the Markdown page. This will be added using <style scoped> so it will only apply to the markdown page. Useful for styling only the HTML generated by the MarkdownIt plugin.


Type: boolean

Whether to add v-once to the entire Markdown page. This will prevent the Markdown page from being re-rendered when the Vue component is updated.

Warning: This will disable demo blocks. Only use this if you have a large document and don't need demo blocks.



Another Vite plugin for compiling Markdown files to Vue components.

This plugin has drawn inspiration from it but has a different feature set. This plugin only supports Vue.js code in code blocks.


View Github