Examples
Every snippet on this page is produced by a single <<<vue line pointing at a component in playground/components. Run npm run docs:dev, edit one of those files, and the page updates.
Template, script setup and scoped style
md
<<<vue ./components/Counter.vuetemplate
<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;
}Both script blocks and several styles
A plain <script> next to <script setup> gets its own tab, and so does each <style>, scoped or not, in source order.
md
<<<vue ./components/TodoList.vuetemplate
<form class="todo-form" @submit.prevent="add">
<input v-model="draft" placeholder="What needs doing?" />
<button type="submit" :disabled="!draft.trim()">Add</button>
</form>
<ul>
<li v-for="todo in todos" :key="todo.id" :class="{ done: todo.done }">
<label><input v-model="todo.done" type="checkbox" /> {{ todo.text }}</label>
</li>
</ul>ts
import { ref } from 'vue';
const draft = ref('');
const todos = ref<Todo[]>([{ id: 1, text: 'Read the real file', done: true }]);
const add = (): void => {
todos.value.push({ id: todos.value.length + 1, text: draft.value.trim(), done: false });
draft.value = '';
};ts
export interface Todo {
id: number;
text: string;
done: boolean;
}css
.todo-form {
display: flex;
gap: 8px;
}
.done {
text-decoration: line-through;
opacity: 0.6;
}css
.todo-form input {
padding: 4px 8px;
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
}Custom blocks
Custom blocks such as <i18n> become a tab named after the block, highlighted with its lang attribute.
md
<<<vue ./components/Greeting.vuetemplate
<p>{{ t('hello', { name }) }}</p>ts
import { useI18n } from 'vue-i18n';
defineProps<{ name: string }>();
const { t } = useI18n({ useScope: 'local' });json
{
"en": { "hello": "Hello, {name}!" },
"fr": { "hello": "Bonjour, {name} !" }
}Path from the markdown root
A leading @ points to the markdown root, wherever the page sits.
md
<<<vue @/components/Counter.vuetemplate
<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;
}Missing file
A path that does not resolve to a file renders a message instead of failing the build.
md
<<<vue ./components/Missing.vueVue snippet path not found: /home/runner/work/markdown-it-sfc-tabs-snippet/markdown-it-sfc-tabs-snippet/playground/components/Missing.vue