Skip to content

/web-meta-framework-vitepress

VitePress 1.x — Vue-powered static site generator for documentation sites, built on Vite

shell
$ npx -y skills add agents-inc/skills --skill web-meta-framework-vitepress --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/web-meta-framework-vitepress
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

VitePress 1.x — Vue-powered static site generator for documentation sites, built on Vite

SKILL.md

web-meta-framework-vitepress.SKILL.md
name: web-meta-framework-vitepress
description: VitePress 1.x — Vue-powered static site generator for documentation sites, built on Vite

VitePress

> **Quick Guide:** VitePress is a Vue-powered static site generator built on Vite, designed for documentation. All config lives in `.vitepress/config.ts`. Use `defineConfig()` for type safety. Sidebar accepts arrays (single) or objects keyed by path prefix (multi-sidebar). Data loaders (`*.data.ts`) run at build time and ship only serialized results to the client. Vue components work directly in Markdown via `<script setup>`. Extend the default theme through layout slots and CSS variables rather than forking it. > > **Current stable version:** VitePress 1.6.x (2026). Uses Vite 6+ and Vue 3.5+.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md**

**(You MUST use `.vitepress/config.ts` with `defineConfig()` for all site configuration — VitePress does not support config outside `.vitepress/`)**

**(You MUST use data loader files (`*.data.ts`) for build-time data — never fetch data at runtime in SSR-unsafe ways)**

**(You MUST handle SSR compatibility — no bare `window`, `document`, or browser APIs outside `onMounted` or `<ClientOnly>`)**

**(You MUST extend the default theme via `extends: DefaultTheme` and layout slots — do not fork the entire theme)**

**(You MUST use `createContentLoader()` for markdown collection pages — it handles caching, watching, and frontmatter extraction)**

</critical_requirements>

---

**Auto-detection:** VitePress, vitepress, .vitepress/config, defineConfig vitepress, createContentLoader, vitepress/theme, DefaultTheme, useData, useSidebar, markdown-it plugin vitepress, vitepress deploy

**When to use:**

  • Building documentation sites from Markdown files
  • Creating blog index/archive pages with `createContentLoader`
  • Customizing the default theme (nav, sidebar, layout slots, CSS variables)
  • Adding Vue components to Markdown pages
  • Configuring markdown-it plugins for extended syntax
  • Setting up multi-sidebar navigation by path prefix
  • Generating sitemaps and other build artifacts with build hooks
  • Internationalization (i18n) with multi-locale routing

**When NOT to use:**

  • Full web applications with complex client-side routing (use a web framework)
  • Sites requiring server-side runtime logic (VitePress is static output)
  • Projects already using Docusaurus, Nextra, or Starlight (those are separate ecosystems)
  • Content that needs a CMS backend (VitePress reads Markdown files at build time)
  • API documentation from OpenAPI specs (use a dedicated OpenAPI tool)

---

<patterns>

Core Patterns

Pattern 1: Site Configuration

All configuration lives in `.vitepress/config.ts`. Use `defineConfig()` for type checking and autocompletion.

import { defineConfig } from "vitepress";

export default defineConfig({
  title: "My Docs",
  description: "Documentation site",
  cleanUrls: true,
  lastUpdated: true,
  sitemap: { hostname: "https://docs.example.com" },

  themeConfig: {
    nav: [
      { text: "Guide", link: "/guide/" },
      { text: "API", link: "/api/" },
    ],
    sidebar: {
      /* see Pattern 2 */
    },
    socialLinks: [{ icon: "github", link: "https://github.com/org/repo" }],
    search: { provider: "local" },
    editLink: {
      pattern: "https://github.com/org/repo/edit/main/docs/:path",
    },
  },
});

**Why good:** `cleanUrls: true` removes `.html` extensions, `sitemap` auto-generates sitemap.xml, `lastUpdated` reads git timestamps, `search.provider: 'local'` enables built-in search with zero config

> **Full examples:** See [examples/core.md](examples/core.md) for complete config, multi-sidebar, i18n, and markdown config.

---

Pattern 2: Multi-Sidebar

Sidebar can be an array (global) or an object keyed by URL path prefix (multi-sidebar). Each section supports `collapsed` for expandable groups.

sidebar: {
  '/guide/': [
    {
      text: 'Getting Started',
      collapsed: false,
      items: [
        { text: 'Introduction', link: '/guide/introduction' },
        { text: 'Installation', link: '/guide/installation' },
      ],
    },
    {
      text: 'Advanced',
      collapsed: true,
      items: [
        { text: 'Data Loaders', link: '/guide/data-loading' },
        { text: 'Deployment', link: '/guide/deploy' },
      ],
    },
  ],
  '/api/': [
    {
      text: 'API Reference',
      items: [
        { text: 'Config', link: '/api/config' },
        { text: 'Runtime API', link: '/api/runtime' },
      ],
    },
  ],
}

**Why good:** Each path prefix gets its own sidebar navigation, `collapsed: true` keeps dense sidebars scannable

**Common mistake:** Using `/guide` without trailing slash — VitePress matches path prefixes, so `/guide/` is more precise than `/guide` (which would also match `/guidelines`)

---

Pattern 3: Data Loaders

Data loaders (`*.data.ts` files) execute at build time. Results are serialized and shipped to client components. Use `createContentLoader` for Markdown collections, custom `load()` for arbitrary data.

// posts.data.ts
import { createContentLoader } from "vitepress";

export default createContentLoader("blog/posts/*.md", {
  excerpt: true,
  transform(rawData) {
    return rawData
      .sort(
        (a, b) => +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date),
      )
      .map(({ url, frontmatter, excerpt }) => ({
        title: frontmatter.title,
        url,
        date: frontmatter.date,
        excerpt,
      }));
  },
});
<!-- blog/index.md — consume in Vue -->
<script setup>
import { data as posts } from "./posts.data";
</script>

<template>
  <article v-for="post in posts" :key="post.url">
    <h2>
      <a :href="post.url">{{ post.title }}</a>
    </h2>
    <time>{{ post.date }}</time>
    <div v-html="post.excerpt" />
  </article>
</template>

**Why good:** `createContentLoader` handles file

Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked