Vitepress
Anthony FuCommunityCreated by Anthony Fu
- Skill
- Tool integration
- Software development
- MIT
- No issues found
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
Download the skill as a ZIP:
https://autogineer.com/agent-skills/antfu/vitepress/downloadUnzip 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
.mdfilesVue 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.tsfor site configurationLook at
.vitepress/theme/for custom theme extensionsThe
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
| Topic | Description | Reference |
|---|---|---|
| Configuration | Config file setup, defineConfig, site metadata | core-config |
| CLI | Command-line interface: dev, build, preview, init | core-cli |
| Routing | File-based routing, source directory, rewrites | core-routing |
| Markdown | Frontmatter, containers, tables, anchors, includes | core-markdown |
Features
Code & Content
| Topic | Description | Reference |
|---|---|---|
| Code Blocks | Syntax highlighting, line highlighting, diffs, focus | features-code-blocks |
| Vue in Markdown | Components, script setup, directives, templating | features-vue |
| Data Loading | Build-time data loaders, createContentLoader | features-data-loading |
| Dynamic Routes | Generate pages from data, paths loader files | features-dynamic-routes |
Theme
| Topic | Description | Reference |
|---|---|---|
| Theme Config | Nav, sidebar, search, social links, footer | theme-config |
| Customization | CSS variables, slots, fonts, global components | theme-customization |
| Custom Theme | Building themes from scratch, theme interface | theme-custom |
Advanced
| Topic | Description | Reference |
|---|---|---|
| Internationalization | Multi-language sites, locale configuration | advanced-i18n |
| SSR Compatibility | Server-side rendering, ClientOnly, dynamic imports | advanced-ssr |
Recipes
| Topic | Description | Reference |
|---|---|---|
| Deployment | GitHub Pages, Netlify, Vercel, Cloudflare, Nginx | recipes-deploy |
Files
- ATTRIBUTION.mdAdded by AutoGineer904 B
- GENERATION.md139 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md3.6 KiB
- references/advanced-i18n.md6.3 KiB
- references/advanced-ssr.md4.0 KiB
- references/core-cli.md2.5 KiB
- references/core-config.md7.1 KiB
- references/core-markdown.md6.3 KiB
- references/core-routing.md4.0 KiB
- references/features-code-blocks.md3.6 KiB
- references/features-data-loading.md4.3 KiB
- references/features-dynamic-routes.md4.9 KiB
- references/features-vue.md3.6 KiB
- references/recipes-deploy.md5.3 KiB
- references/theme-config.md6.9 KiB
- references/theme-custom.md5.7 KiB
- references/theme-customization.md8.3 KiB
references/theme-customization.md
name: extending-vitepress-default-theme description: Customize CSS variables, use layout slots, register global components, and override theme fonts
Extending Default Theme
Customize the default theme through CSS, slots, and Vue components.
Theme Entry File
Create .vitepress/theme/index.ts to extend the default theme:
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import './custom.css'
export default DefaultThemeCSS Variables
Override root CSS variables:
/* .vitepress/theme/custom.css */
:root {
/* Brand colors */
--vp-c-brand-1: #646cff;
--vp-c-brand-2: #747bff;
--vp-c-brand-3: #9499ff;
/* Backgrounds */
--vp-c-bg: #ffffff;
--vp-c-bg-soft: #f6f6f7;
/* Text */
--vp-c-text-1: #213547;
--vp-c-text-2: #476582;
}
.dark {
--vp-c-brand-1: #747bff;
--vp-c-bg: #1a1a1a;
}See all CSS variables.
Navbar (v2)
The navbar draws a single background surface controlled by CSS variables, so a frosted-glass bar needs no component overrides:
:root {
--vp-nav-height: 4rem;
--vp-nav-bg-color: color-mix(in srgb, var(--vp-c-bg) 65%, transparent);
--vp-nav-home-bg-color: transparent; /* while unscrolled on the home page */
--vp-nav-backdrop-filter: saturate(180%) blur(8px);
--vp-nav-divider-color: var(--vp-c-gutter);
--vp-nav-screen-bg-color: var(--vp-c-bg);
}When nav items don't fit, they collapse into a ⋯ overflow menu (label it with
extraMenuLabel). Note backdrop-filter has a scroll cost and Safari ≤17 skips
variable-driven backdrop filters.
Home Hero Customization
:root {
/* Gradient name color */
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: linear-gradient(120deg, #bd34fe, #41d1ff);
/* Hero image glow */
--vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
--vp-home-hero-image-filter: blur(44px);
}Custom Fonts
Remove Inter font and use your own:
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme-without-fonts'
import './fonts.css'
export default DefaultTheme/* .vitepress/theme/fonts.css */
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
}
:root {
--vp-font-family-base: 'MyFont', sans-serif;
--vp-font-family-mono: 'Fira Code', monospace;
}Preload fonts in config:
// .vitepress/config.ts
export default {
transformHead({ assets }) {
const fontFile = assets.find(file => /myfont\.[\w-]+\.woff2/.test(file))
if (fontFile) {
return [
['link', { rel: 'preload', href: fontFile, as: 'font', type: 'font/woff2', crossorigin: '' }]
]
}
}
}Global Components
Register components available in all markdown:
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import MyComponent from './components/MyComponent.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('MyComponent', MyComponent)
}
}Use in markdown:
<MyComponent :prop="value" />Layout Slots
Inject content into specific locations:
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import MyLayout from './MyLayout.vue'
export default {
extends: DefaultTheme,
Layout: MyLayout
}<!-- .vitepress/theme/MyLayout.vue -->
<script setup>
import DefaultTheme from 'vitepress/theme'
const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #aside-outline-before>
<div>Above outline</div>
</template>
<template #doc-before>
<div>Before doc content</div>
</template>
<template #doc-after>
<div>After doc content</div>
</template>
</Layout>
</template>Available Slots
Doc layout (layout: doc):
doc-top,doc-bottomdoc-before,doc-afterdoc-footer-beforesidebar-nav-before,sidebar-nav-afteraside-top,aside-bottomaside-outline-before,aside-outline-afteraside-ads-before,aside-ads-after
Home layout (layout: home):
home-hero-before,home-hero-afterhome-hero-info-before,home-hero-info,home-hero-info-afterhome-hero-actions-before-actions,home-hero-actions-after,home-hero-imagehome-features-before,home-features-after
Page layout (layout: page):
page-top,page-bottom
Always available:
layout-top,layout-bottomnav-bar-title-before,nav-bar-title-afternav-bar-content-before,nav-bar-content-afternot-found(404 page)
Using Render Functions
Alternative to template slots:
// .vitepress/theme/index.ts
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import MyComponent from './MyComponent.vue'
export default {
extends: DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'aside-outline-before': () => h(MyComponent)
})
}
}Override Internal Components
Replace default theme components with Vite aliases:
// .vitepress/config.ts
import { fileURLToPath, URL } from 'node:url'
export default {
vite: {
resolve: {
alias: [
{
find: /^.*\/VPNavBar\.vue$/,
replacement: fileURLToPath(
new URL('./theme/components/CustomNavBar.vue', import.meta.url)
)
}
]
}
}
}View Transitions
Custom dark mode toggle animation:
<!-- .vitepress/theme/Layout.vue -->
<script setup>
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { nextTick, provide } from 'vue'
const { isDark } = useData()
provide('toggle-appearance', async ({ clientX: x, clientY: y }) => {
if (!document.startViewTransition) {
isDark.value = !isDark.value
return
}
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y))}px at ${x}px ${y}px)`
]
await document.startViewTransition(async () => {
isDark.value = !isDark.value
await nextTick()
}).ready
document.documentElement.animate(
{ clipPath: isDark.value ? clipPath.reverse() : clipPath },
{ duration: 300, easing: 'ease-in', pseudoElement: `::view-transition-${isDark.value ? 'old' : 'new'}(root)` }
)
})
</script>
<template>
<DefaultTheme.Layout />
</template>Icons (v2)
Render iconify icons through VitePress's pipeline (no external fetch). Use the
VPIcon component from vitepress/theme (accepts collection:name or { svg }):
<VPIcon icon="lucide:rocket" />Or the useIcon composable, passing the element ref so dev mode can resolve it:
<script setup>
import { useIcon } from 'vitepress'
import { useTemplateRef } from 'vue'
const el = useTemplateRef('el')
const iconClass = useIcon('lucide:rocket', el)
</script>
<template><span ref="el" :class="iconClass" /></template>Client-only icons (inside <ClientOnly>) aren't collected during build — list
them in icons.include.
Route Change Hooks & setup (v2)
Assign navigation handlers on the router (return false to cancel), and use the
setup hook to run Composition API code inside the root component's setup():
// .vitepress/theme/index.ts
import { watch } from 'vue'
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
enhanceApp({ router }) {
router.onBeforeRouteChange = (to) => { /* return false to cancel */ }
router.onAfterRouteChange = (to) => console.log('navigated to', to)
},
setup() {
const { page } = useData()
watch(() => page.value.relativePath, (p) => console.log('now viewing', p))
}
}setup also runs during SSR/SSG — keep browser-only work in onMounted.
Key Points
Import
vitepress/theme-without-fontsto use custom fontsUse layout slots to inject content without overriding components
Global components are registered in
enhanceAppOverride CSS variables for theming (v2 adds navbar surface variables)
Use Vite aliases to replace internal components
v2:
VPIcon/useIconfor iconify icons, routeronBeforeRouteChange/onAfterRouteChange, and a themesetuphook
<!-- Source references: - https://vitepress.dev/guide/extending-default-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 or Anthony Fu.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download vitepress.zip