All skills
antfu avatar

/vitepress

@d02c484 official
by Anthony Fuantfu/skills5.9k stars
335

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

Use this Skill: https://skilld.dev/gh/antfu/skills/vitepress

This session only. Nothing lands on disk.

referencesadvanced-i18n.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Internationalization

VitePress supports multi-language sites through locale configuration.

Directory Structure

Organize content by locale:

docs/
├─ en/
│  ├─ guide.md
│  └─ index.md
├─ zh/
│  ├─ guide.md
│  └─ index.md
└─ fr/
   ├─ guide.md
   └─ index.md

Or with root as default language:

docs/
├─ guide.md        # English (root)
├─ index.md
├─ zh/
│  ├─ guide.md
│  └─ index.md
└─ fr/
   ├─ guide.md
   └─ index.md

Configuration

// .vitepress/config.ts
import { defineConfig } from 'vitepress'

export default defineConfig({
  locales: {
    root: {
      label: 'English',
      lang: 'en'
    },
    zh: {
      label: '简体中文',
      lang: 'zh-CN',
      link: '/zh/'
    },
    fr: {
      label: 'Français',
      lang: 'fr',
      link: '/fr/'
    }
  }
})

Locale-Specific Config

Override site config per locale:

locales: {
  root: {
    label: 'English',
    lang: 'en',
    title: 'My Docs',
    description: 'Documentation site',
    themeConfig: {
      nav: [
        { text: 'Guide', link: '/guide/' }
      ],
      sidebar: {
        '/guide/': [
          { text: 'Introduction', link: '/guide/' }
        ]
      }
    }
  },
  zh: {
    label: '简体中文',
    lang: 'zh-CN',
    link: '/zh/',
    title: '我的文档',
    description: '文档站点',
    themeConfig: {
      nav: [
        { text: '指南', link: '/zh/guide/' }
      ],
      sidebar: {
        '/zh/guide/': [
          { text: '介绍', link: '/zh/guide/' }
        ]
      }
    }
  }
}

Locale-Specific Properties

Each locale can override:

interface LocaleSpecificConfig {
  lang?: string
  dir?: 'ltr' | 'rtl' | 'auto'
  title?: string
  titleTemplate?: string | boolean
  description?: string
  head?: HeadConfig[]       // Merged with existing
  themeConfig?: ThemeConfig // Shallow merged
}

Search i18n

Local Search

themeConfig: {
  search: {
    provider: 'local',
    options: {
      locales: {
        zh: {
          translations: {
            button: {
              buttonText: '搜索',
              buttonAriaLabel: '搜索'
            },
            modal: {
              noResultsText: '没有结果',
              resetButtonTitle: '重置搜索',
              footer: {
                selectText: '选择',
                navigateText: '导航',
                closeText: '关闭'
              }
            }
          }
        }
      }
    }
  }
}

Algolia Search

themeConfig: {
  search: {
    provider: 'algolia',
    options: {
      appId: '...',
      apiKey: '...',
      indexName: '...',
      locales: {
        zh: {
          placeholder: '搜索文档',
          translations: {
            button: { buttonText: '搜索文档' }
          }
        }
      }
    }
  }
}

Separate Locale Directories

For fully separated locales without root fallback:

docs/
├─ en/
│  └─ index.md
├─ zh/
│  └─ index.md
└─ fr/
   └─ index.md

Requires server redirect for / → /en/. Netlify example:

/* /en/:splat 302 Language=en
/* /zh/:splat 302 Language=zh
/* /en/:splat 302

Persisting Language Choice

Set cookie on language change:

<!-- .vitepress/theme/Layout.vue -->
<script setup>
import DefaultTheme from 'vitepress/theme'
import { useData, inBrowser } from 'vitepress'
import { watchEffect } from 'vue'

const { lang } = useData()

watchEffect(() => {
  if (inBrowser) {
    document.cookie = `nf_lang=${lang.value}; expires=Mon, 1 Jan 2030 00:00:00 UTC; path=/`
  }
})
</script>

<template>
  <DefaultTheme.Layout />
</template>

Per-locale Markdown Strings (v2)

Override renderer-baked strings (custom container / GitHub-alert default titles, code copy button text) per locale via the markdown key. Values fall back to the root markdown options. Must live in the main config (the renderer is created once for the whole site); registering new containers per-locale is unsupported.

locales: {
  root: { label: 'English', lang: 'en' },
  zh: {
    label: '简体中文',
    lang: 'zh-Hans',
    markdown: {
      container: { tipLabel: '提示', warningLabel: '警告' },
      codeCopyButton: { tooltipText: '复制代码', copiedText: '已复制' }
    }
  }
}

Custom Locale Link (i18nRouting) (v2)

Set themeConfig.i18nRouting to a function to customize the target link when switching locale (see theme-config).

RTL Support (v2)

Native, no longer experimental. Set dir: 'rtl' (site-wide, per-locale, or per page via frontmatter). The default theme uses CSS logical properties, so layout, nav, and directional icons mirror automatically — do not add an RTLCSS PostCSS plugin (it would double-flip). Code blocks stay LTR.

locales: {
  ar: { label: 'العربية', lang: 'ar', dir: 'rtl' }
}

For your own styles, prefer logical properties (margin-inline-start) and mirror custom directional icons:

[dir='rtl'] .my-arrow-icon { scale: -1 1; }

Organizing Config

Split config into separate files:

.vitepress/
├─ config/
│  ├─ index.ts      # Main config, merges locales
│  ├─ en.ts         # English config
│  ├─ zh.ts         # Chinese config
│  └─ shared.ts     # Shared config
// .vitepress/config/index.ts
import { defineConfig } from 'vitepress'
import { shared } from './shared'
import { en } from './en'
import { zh } from './zh'

export default defineConfig({
  ...shared,
  locales: {
    root: { label: 'English', ...en },
    zh: { label: '简体中文', ...zh }
  }
})

Key Points

  • Use locales object in config with root for default language
  • Each locale can override title, description, and themeConfig
  • themeConfig is shallow merged (define complete nav/sidebar per locale)
  • Don't override themeConfig.algolia at locale level
  • v2: dir: 'rtl' enables native RTL (CSS logical properties) — no PostCSS plugin
  • v2: override renderer strings per locale via the markdown key; customize the switch link via i18nRouting function
  • Language switcher appears automatically in nav
<!-- Source references: - https://vitepress.dev/guide/i18n -->

Source: SKILL.md on GitHub

No alerts2d5 checks · Risk SAFE
  • Gen Agent Trust Hub2d

    The skill provides comprehensive documentation and configuration examples for VitePress, a static site generator. No malicious patterns or intent were detected. A minor surface for indirect prompt injection was identified due to the documented features for ingesting external data during the site build process, which is inherent to the framework's functionality.

  • Socket2d

    No alerts

  • Snyk2d

    Risk: LOW · No issues

  • Runlayer7mo

    2/16 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at d02c484. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated 4 days ago
Other metadata
metadata
{
  "author": "Anthony Fu",
  "version": "2026.9.25",
  "source": "Generated from https://github.com/vuejs/vitepress, scripts located at https://github.com/antfu/skills"
}

README badge

README badge for antfu/skills/vitepress

VitePress is a static site generator built on Vite and Vue 3 that converts Markdown files into a fast single-page application, with file-based routing and built-in support for Vue components directly in Markdown. Use it for documentation sites, blogs, and marketing pages where you need configurable themes, syntax-highlighted code blocks, and instant hot-reload during development.

Generated from the current SKILL.md.

Does VitePress work with Vue components embedded in Markdown?
Yes. Vue components work directly in Markdown files, and you can use script setup and directives within Markdown content.
Can I build a multi-language documentation site with VitePress?
Yes. VitePress includes internationalization support with locale configuration for building multi-language sites.
What search options does VitePress provide?
VitePress includes built-in local search or integration with Algolia for full-text search across documentation.
Can I customize the default theme or build a custom one from scratch?
Yes. You can extend the default theme via CSS variables and slots, or build a completely custom theme by implementing the theme interface.
Does VitePress support dynamic route generation?
Yes. You can generate pages from data at build time using createContentLoader and paths loader files for dynamic routing.

Generated from the current SKILL.md. These answers refresh after source changes.