Skip to content

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.vue
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;
}

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.vue
template
<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.vue
template
<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.vue
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;
}

Missing file ​

A path that does not resolve to a file renders a message instead of failing the build.

md
<<<vue ./components/Missing.vue
Vue snippet path not found: /home/runner/work/markdown-it-sfc-tabs-snippet/markdown-it-sfc-tabs-snippet/playground/components/Missing.vue

Released under the MIT License.