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!')
</script>

<template>
    <button @click="clickHandler">
        Click me
    </button>
</template>
```(end)

Install

npm install -D vite-vue-md

Setup

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.

vite.config.js:

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

  export default {
      plugins: [
          // ...

          vue({
+             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!');
</script>

<template>
    <button @click="clickHandler">
        Click me
    </button>
</template>
```(end)

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'
</script>

<template>
    <button @click="clicked">
        Click me
    </button>
</template>

Second file:
 demo=click-handler.js
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 `
        <DemoContainer>
            <!-- Inline the component here -->
            ${componentTag}

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

Options

include

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

Files to include from being compiled as Vue files.

exclude

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

Files to exclude from being compiled as Vue files.

markdownItOptions

Type: markdownIt.Options

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

markdownItSetup

Type: (md: markdownIt) => void;

Callback to add plugins to MarkdownIt.

wrapperClass

Type: string

Default: markdown-body

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

onDemo

Type:

(
    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.

markdownCss

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.

useVOnce

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.

Related

unplugin-vue-markdown

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.

Github

View Github