Skip to content

markdown-it-sfc-tabs-snippetVue components in your docs, straight from the source

One line of markdown imports a .vue file as tabbed code blocks, so the docs can never drift from the code.

Write this ​

md
<<<vue ./components/Counter.vue

Get this ​

template
<button type="button" @click="increment">Count is {{ count }}</button>
ts
import { ref } from 'vue';

const count = ref(0);

const increment = (): void => {
    count.value += 1;
};
css
button {
    color: rebeccapurple;
}

And since the docs import the same file, the live component is one line away:

Install ​

sh
npm i -D markdown-it-sfc-tabs-snippet

Then register it with VitePress, or with any markdown-it instance:

ts
// .vitepress/config.ts
import { defineConfig } from 'vitepress';
import vueSnippet from 'markdown-it-sfc-tabs-snippet';

export default defineConfig({
    markdown: {
        config: (md) => {
            md.use(vueSnippet);
        },
    },
});
ts
import MarkdownIt from 'markdown-it';
import vueSnippet from 'markdown-it-sfc-tabs-snippet';

const md = new MarkdownIt().use(vueSnippet, { root: process.cwd() });

// `path` tells the plugin which page is rendering, so relative paths resolve against it.
md.render(source, { path: '/docs/guide/index.md' });

VitePress renders the group as tabs. Plain markdown-it has no code-group renderer, so the code blocks come out as ordinary <pre><code> blocks inside a <div> wrapper. The containerName option lets you plug in your own container renderer.

The README covers the syntax, the options and plain markdown-it usage in detail.

Released under the MIT License.