Generated banner for Vitepress
Generated logo for Vitepress

Vitepress

Anthony FuCommunityCreated by Anthony Fu

  • Skill
  • Tool integration
  • Software development
  • MIT
  • No issues found

From the author

VitePress static site generator powered by Vite and Vue. Use when building documentation sites, configuring themes, or writing Markdown with Vue components.
— the description by Anthony Fu

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

VitePress is a static site generator that transforms Markdown content into a single-page application. It leverages Vite for build processes and Vue 3 for component-based content, allowing developers to integrate Vue components directly into Markdown files. The tool supports file-based routing, theme customization, and provides built-in features for search, internationalization, and server-side rendering compatibility.

What it does

  • Generates static HTML from Markdown files
  • Enables the use of Vue components within Markdown
  • Supports file-based routing and site configuration
  • Provides tools for internationalization and multi-language sites
  • Offers mechanisms for SSR-compatible code and browser-only component handling
  • Includes built-in search and theme customization options

When to use it

  • When building documentation sites or technical guides
  • When creating blogs or marketing sites using Markdown
  • When you need to embed interactive Vue components in static content
  • When you require a site with multi-language support

Advantages

  • Direct integration of Vue components in Markdown
  • File-based routing simplifies site structure
  • Built-in support for internationalization and RTL layouts
  • Tools for managing browser-only code in an SSR environment

Usage examples

“How do I configure multiple languages in VitePress?”
You can define a locales object in your .vitepress/config.ts file to map language codes to specific site configurations and directory structures.
“How can I use a component that requires the window object?”
You should wrap the component in a ClientOnly tag or use defineClientComponent to ensure it only loads on the client side, avoiding SSR errors.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/antfu/vitepress/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip vitepress.zip -d .agents/skills

Documentation by Anthony Fu

VitePress is a Static Site Generator (SSG) built on Vite and Vue 3. It takes Markdown content, applies a theme, and generates static HTML that becomes an SPA for fast navigation. Perfect for documentation, blogs, and marketing sites.

Key Characteristics:

  • File-based routing with .md files

  • Vue components work directly in Markdown

  • Fast HMR with instant updates (<100ms)

  • Default theme optimized for documentation

  • Built-in search (local or Algolia)

Before working with VitePress projects:

  • Check .vitepress/config.ts for site configuration

  • Look at .vitepress/theme/ for custom theme extensions

  • The public/ directory contains static assets served as-is

The skill is based on VitePress 2.0.0-alpha.20, generated at 2026-09-25.

VitePress 2 notes (v1 → v2): install with vitepress@next; requires Node.js 22+. defineConfigWithTheme is deprecated — use defineConfig<ThemeConfig>. Native RTL support (dir option, CSS logical properties) replaces the old PostCSS-plugin approach. Built-in iconify pipeline (icons config, useIcon/VPIcon, collection:name social icons). New assetsBase (CDN) and assetsShards build options; metaChunk removed. Markdown image.lazyLoading renamed to image.lazyLoad.

Core

TopicDescriptionReference
ConfigurationConfig file setup, defineConfig, site metadatacore-config
CLICommand-line interface: dev, build, preview, initcore-cli
RoutingFile-based routing, source directory, rewritescore-routing
MarkdownFrontmatter, containers, tables, anchors, includescore-markdown

Features

Code & Content
TopicDescriptionReference
Code BlocksSyntax highlighting, line highlighting, diffs, focusfeatures-code-blocks
Vue in MarkdownComponents, script setup, directives, templatingfeatures-vue
Data LoadingBuild-time data loaders, createContentLoaderfeatures-data-loading
Dynamic RoutesGenerate pages from data, paths loader filesfeatures-dynamic-routes

Theme

TopicDescriptionReference
Theme ConfigNav, sidebar, search, social links, footertheme-config
CustomizationCSS variables, slots, fonts, global componentstheme-customization
Custom ThemeBuilding themes from scratch, theme interfacetheme-custom

Advanced

TopicDescriptionReference
InternationalizationMulti-language sites, locale configurationadvanced-i18n
SSR CompatibilityServer-side rendering, ClientOnly, dynamic importsadvanced-ssr

Recipes

TopicDescriptionReference
DeploymentGitHub Pages, Netlify, Vercel, Cloudflare, Nginxrecipes-deploy

Files

references/theme-custom.md


name: vitepress-custom-themes description: Building custom themes from scratch with the theme interface, Layout component, and enhanceApp

Custom Themes

Build a theme from scratch when the default theme doesn't fit your needs.

Theme Entry

Create .vitepress/theme/index.ts:

// .vitepress/theme/index.ts
import Layout from './Layout.vue'

export default {
  Layout,
  enhanceApp({ app, router, siteData }) {
    // Register global components, plugins, etc.
  }
}

Theme Interface

interface Theme {
  // Required: Root layout component
  Layout: Component
  
  // Optional: Enhance Vue app instance
  enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
  
  // Optional (v2): runs inside the root component's setup()
  setup?: () => void
  
  // Optional: Extend another theme (its enhanceApp & setup run first)
  extends?: Theme
}

interface EnhanceAppContext {
  app: App              // Vue app instance
  router: Router        // VitePress router
  siteData: Ref<SiteData>  // Site-level metadata
}

Basic Layout

The Layout component must render <Content /> for markdown:

<!-- .vitepress/theme/Layout.vue -->
<script setup>
import { useData } from 'vitepress'
const { page, frontmatter } = useData()
</script>

<template>
  <div class="layout">
    <header>
      <nav>My Site</nav>
    </header>
    
    <main>
      <div v-if="page.isNotFound">
        <h1>404 - Page Not Found</h1>
      </div>
      
      <div v-else-if="frontmatter.layout === 'home'">
        <h1>Welcome!</h1>
      </div>
      
      <article v-else>
        <Content />
      </article>
    </main>
    
    <footer>
      <p>© 2024 My Site</p>
    </footer>
  </div>
</template>

Runtime API

Access VitePress data in your theme:

<script setup>
import { useData, useRoute, useRouter } from 'vitepress'

// Page and site data
const { 
  site,        // Site config (title, description, etc.)
  theme,       // Theme config
  page,        // Current page data
  frontmatter, // Current page frontmatter
  title,       // Page title
  description, // Page description
  lang,        // Current language
  isDark,      // Dark mode state
  params       // Dynamic route params
} = useData()

// Routing
const route = useRoute()
const router = useRouter()

// Navigate programmatically
const goToGuide = () => router.go('/guide/')
</script>
Route Change Hooks (v2)

Assign handlers on the router instance (also available via enhanceApp's router). Return false from onBeforeRouteChange/onBeforePageLoad to cancel:

const router = useRouter()
router.onBeforeRouteChange = (to) => { /* return false to cancel */ }
router.onAfterRouteChange = (to) => console.log('navigated to', to)

Built-in Components

<script setup>
import { Content } from 'vitepress'
</script>

<template>
  <!-- Renders markdown content -->
  <Content />
  
  <!-- Renders slot only on client (SSR-safe) -->
  <ClientOnly>
    <NonSSRComponent />
  </ClientOnly>
</template>

Extend Another Theme

Build on top of default theme or any other:

// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    // Your customizations
  }
}

Register Plugins and Components

// .vitepress/theme/index.ts
import Layout from './Layout.vue'
import GlobalComponent from './GlobalComponent.vue'

export default {
  Layout,
  enhanceApp({ app }) {
    // Register global component
    app.component('GlobalComponent', GlobalComponent)
    
    // Register plugin
    app.use(MyPlugin)
    
    // Provide/inject
    app.provide('key', value)
  }
}

Async enhanceApp

For plugins that need async initialization:

export default {
  Layout,
  async enhanceApp({ app }) {
    if (!import.meta.env.SSR) {
      // Client-only plugin
      const plugin = await import('browser-only-plugin')
      app.use(plugin.default)
    }
  }
}

Theme-Aware Layout

Handle different page layouts:

<script setup>
import { useData } from 'vitepress'
import Home from './Home.vue'
import Doc from './Doc.vue'
import Page from './Page.vue'
import NotFound from './NotFound.vue'

const { page, frontmatter } = useData()
</script>

<template>
  <NotFound v-if="page.isNotFound" />
  <Home v-else-if="frontmatter.layout === 'home'" />
  <Page v-else-if="frontmatter.layout === 'page'" />
  <Doc v-else />
</template>

Distributing a Theme

As npm package:

// my-theme/index.ts
import Layout from './Layout.vue'
export default { Layout }

// Export types for config
export type { ThemeConfig } from './types'

Consumer usage:

// .vitepress/theme/index.ts
import Theme from 'my-vitepress-theme'

export default Theme

// Or extend it
export default {
  extends: Theme,
  enhanceApp({ app }) {
    // Additional customization
  }
}

Theme Config Types

For custom theme config types, pass the type to defineConfig (v2 — defineConfigWithTheme is deprecated):

// .vitepress/config.ts
import { defineConfig } from 'vitepress'
import type { ThemeConfig } from 'my-theme'

export default defineConfig<ThemeConfig>({
  themeConfig: {
    // Type-checked theme config
  }
})

Key Points

  • Theme must export Layout component

  • <Content /> renders the markdown content

  • Use useData() to access page/site data

  • enhanceApp runs on both server and client

  • Check import.meta.env.SSR for client-only code

  • Use extends to build on existing themes

  • v2: theme setup hook runs inside root setup(); router onBeforeRouteChange/onAfterRouteChange for navigation hooks; use defineConfig<ThemeConfig> (not defineConfigWithTheme)

<!-- Source references: - https://vitepress.dev/guide/custom-theme -->

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Anthony Fu
Publisher
Anthony Fu (Community)
Source
antfu/skills · skills/vitepress · commit f63e9ec
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE.md)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Anthony Fu.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download vitepress.zip