Never out of date
Tabs are read from the real component file at build time. Change the component, the docs follow.
One line of markdown imports a .vue file as tabbed code blocks, so the docs can never drift from the code.
<<<vue ./components/Counter.vue<button type="button" @click="increment">Count is {{ count }}</button>import { ref } from 'vue';
const count = ref(0);
const increment = (): void => {
count.value += 1;
};button {
color: rebeccapurple;
}And since the docs import the same file, the live component is one line away:
npm i -D markdown-it-sfc-tabs-snippetThen register it with VitePress, or with any markdown-it instance:
// .vitepress/config.ts
import { defineConfig } from 'vitepress';
import vueSnippet from 'markdown-it-sfc-tabs-snippet';
export default defineConfig({
markdown: {
config: (md) => {
md.use(vueSnippet);
},
},
});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.