Skip to main content

Theme API

VitePress themes are defined using a standard interface and can extend the default theme or create completely custom layouts.

Theme Interface

Theme Object

A VitePress theme is defined as an object with the following interface:
import type { Theme } from 'vitepress'

const theme: Theme = {
  Layout: MyLayout,
  enhanceApp({ app, router, siteData }) {
    // App-level enhancements
  },
  extends: BaseTheme,
  setup() {
    // Theme-level setup (deprecated)
  },
  NotFound: Custom404 // deprecated
}

export default theme
Layout
Component
The root layout component for your theme
enhanceApp
(ctx: EnhanceAppContext) => Awaitable<void>
Function to enhance the Vue app instance
extends
Theme
Another theme to extend from
setup
() => void
Theme-level setup function (deprecated - use Layout component setup instead)
NotFound
Component
Custom 404 component (deprecated - check useData().page.value.isNotFound in Layout)

EnhanceAppContext

The context object passed to enhanceApp:
interface EnhanceAppContext {
  app: App        // Vue app instance
  router: Router  // VitePress router
  siteData: Ref<SiteData>  // Site configuration
}
Example Usage:
import DefaultTheme from 'vitepress/theme'
import CustomButton from './components/CustomButton.vue'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    // Register global components
    app.component('CustomButton', CustomButton)
  }
}

Default Theme

The default theme can be imported from vitepress/theme.

Importing the Default Theme

import DefaultTheme from 'vitepress/theme'

export default DefaultTheme

Without Fonts

Import the default theme without Inter font:
import DefaultTheme from 'vitepress/theme-without-fonts'

export default DefaultTheme

Default Theme Components

The default theme exports several components you can use in your custom theme or markdown:

Layout Components

VPBadge

Display a badge with different styles.
<script setup>
import { VPBadge } from 'vitepress/theme'
</script>

<template>
  <VPBadge type="info" text="New" />
  <VPBadge type="tip" text="Updated" />
  <VPBadge type="warning" text="Deprecated" />
  <VPBadge type="danger" text="Breaking" />
</template>
type
'info' | 'tip' | 'warning' | 'danger'
default:"tip"
Badge color theme
text
string
Badge text content
In Markdown:
# API <Badge type="info" text="v2.0+" />

VPButton

Stylized button component.
<script setup>
import { VPButton } from 'vitepress/theme'
</script>

<template>
  <VPButton href="/get-started" text="Get Started" theme="brand" />
  <VPButton href="/docs" text="Documentation" theme="alt" />
</template>
theme
'brand' | 'alt' | 'sponsor'
Button style theme
text
string
Button text
href
string
Link URL
size
'small' | 'medium' | 'big'
default:"medium"
Button size

VPImage

Responsive image component with light/dark mode support.
<script setup>
import { VPImage } from 'vitepress/theme'
</script>

<template>
  <VPImage 
    image="/logo.png"
    alt="Logo" 
  />
  
  <!-- Different images for light/dark mode -->
  <VPImage 
    :image="{
      light: '/logo-light.png',
      dark: '/logo-dark.png'
    }"
    alt="Logo" 
  />
</template>
image
string | { light: string, dark: string }
required
Image source URL or theme-specific URLs
alt
string
required
Alternative text for the image

Home Page Components

VPHomeHero

Hero section for home pages.
<script setup>
import { VPHomeHero } from 'vitepress/theme'
</script>

<template>
  <VPHomeHero />
</template>
Reads hero configuration from page frontmatter:
---
layout: home
hero:
  name: VitePress
  text: Vite & Vue powered static site generator
  tagline: Simple, powerful, and fast
  image:
    src: /logo.png
    alt: VitePress
  actions:
    - theme: brand
      text: Get Started
      link: /quickstart
    - theme: alt
      text: View on GitHub
      link: https://github.com/vuejs/vitepress
---

VPHomeFeatures

Features grid for home pages.
<script setup>
import { VPHomeFeatures } from 'vitepress/theme'
</script>

<template>
  <VPHomeFeatures />
</template>
Reads features from page frontmatter:
---
layout: home
features:
  - icon: ⚡️
    title: Vite-Powered
    details: Instant server start and lightning fast HMR
  - icon: 🖖
    title: Vue-Enhanced
    details: Use Vue components directly in markdown
  - icon: 🛠️
    title: Simple and Minimal
    details: Markdown-centered with minimal configuration
---

VPHomeContent

Wrapper for custom home page content.
<script setup>
import { VPHomeContent } from 'vitepress/theme'
</script>

<template>
  <VPHomeContent>
    <!-- Your custom home content -->
  </VPHomeContent>
</template>

VPHomeSponsors

Display sponsors on the home page.
<script setup>
import { VPHomeSponsors } from 'vitepress/theme'

const sponsors = [
  {
    tier: 'Platinum',
    size: 'big',
    items: [
      { name: 'Company A', url: 'https://a.com', img: '/sponsors/a.png' },
      { name: 'Company B', url: 'https://b.com', img: '/sponsors/b.png' }
    ]
  }
]
</script>

<template>
  <VPHomeSponsors :data="sponsors" />
</template>

Team Components

VPTeamPage

Wrapper component for team pages.
<script setup>
import { VPTeamPage } from 'vitepress/theme'
</script>

<template>
  <VPTeamPage>
    <template #title>Our Team</template>
    <template #lead>The awesome people behind the project</template>
  </VPTeamPage>
</template>

VPTeamPageTitle

Title section for team pages.
<script setup>
import { VPTeamPageTitle } from 'vitepress/theme'
</script>

<template>
  <VPTeamPageTitle>
    <template #title>Meet Our Team</template>
    <template #lead>Dedicated individuals making it happen</template>
  </VPTeamPageTitle>
</template>

VPTeamPageSection

Section wrapper for grouping team members.
<script setup>
import { VPTeamPageSection } from 'vitepress/theme'
</script>

<template>
  <VPTeamPageSection>
    <template #title>Core Team</template>
    <template #lead>The maintainers of the project</template>
    <template #members>
      <!-- Team members -->
    </template>
  </VPTeamPageSection>
</template>

VPTeamMembers

Display team member cards.
<script setup>
import { VPTeamMembers } from 'vitepress/theme'

const members = [
  {
    avatar: 'https://github.com/yyx990803.png',
    name: 'Evan You',
    title: 'Creator',
    links: [
      { icon: 'github', link: 'https://github.com/yyx990803' },
      { icon: 'twitter', link: 'https://twitter.com/youyuxi' }
    ]
  }
]
</script>

<template>
  <VPTeamMembers :members="members" />
</template>
members
TeamMember[]
required
Array of team member objects
size
'small' | 'medium'
default:"medium"
Size of member cards
TeamMember Type:
interface TeamMember {
  avatar: string
  name: string
  title?: string
  org?: string
  orgLink?: string
  desc?: string
  links?: SocialLink[]
  sponsor?: string
  actionText?: string
}

Social Components

Display a group of social media links.
<script setup>
import { VPSocialLinks } from 'vitepress/theme'

const links = [
  { icon: 'github', link: 'https://github.com/vuejs/vitepress' },
  { icon: 'twitter', link: 'https://twitter.com/vite_js' },
  { icon: 'discord', link: 'https://chat.vitejs.dev' }
]
</script>

<template>
  <VPSocialLinks :links="links" />
</template>

Single social media link icon.
<script setup>
import { VPSocialLink } from 'vitepress/theme'
</script>

<template>
  <VPSocialLink 
    icon="github" 
    link="https://github.com/vuejs/vitepress" 
  />
</template>
icon
string | { svg: string }
required
Icon name or custom SVG
URL to link to
ariaLabel
string
Accessibility label
Built-in Icons:
  • discord
  • facebook
  • github
  • instagram
  • linkedin
  • mastodon
  • slack
  • twitter
  • youtube
  • x
Custom SVG:
<VPSocialLink 
  :icon="{ svg: '<svg>...</svg>' }" 
  link="https://example.com" 
/>

Other Components

VPSponsors

Display sponsor logos in a grid.
<script setup>
import { VPSponsors } from 'vitepress/theme'

const data = [
  {
    tier: 'Platinum Sponsors',
    size: 'big',
    items: [
      { name: 'Sponsor 1', url: 'https://...', img: '/sponsors/1.png' }
    ]
  }
]
</script>

<template>
  <VPSponsors :data="data" />
</template>

VPDocAsideSponsors

Sponsors section for the aside/sidebar.
<script setup>
import { VPDocAsideSponsors } from 'vitepress/theme'
</script>

<template>
  <VPDocAsideSponsors />
</template>
Reads sponsors from theme config carbonAds or sidebar.sponsors.

VPFeatures

Alternative features component.
<script setup>
import { VPFeatures } from 'vitepress/theme'

const features = [
  {
    icon: '⚡️',
    title: 'Fast',
    details: 'Lightning fast performance'
  }
]
</script>

<template>
  <VPFeatures :features="features" />
</template>

Default Theme Composables

useLayout

Access layout state and computed properties.
import { useLayout } from 'vitepress/theme'

const {
  isHome,
  sidebar,
  sidebarGroups,
  hasSidebar,
  isSidebarEnabled,
  hasAside,
  leftAside,
  headers,
  hasLocalNav
} = useLayout()
isHome
ComputedRef<boolean>
Whether the current page is the home page
sidebar
Ref<SidebarItem[]>
Current sidebar items
sidebarGroups
ComputedRef<SidebarItem[]>
Grouped sidebar items
hasSidebar
ComputedRef<boolean>
Whether sidebar should be displayed
isSidebarEnabled
ComputedRef<boolean>
Whether sidebar is enabled at current viewport
hasAside
ComputedRef<boolean>
Whether aside/outline should be displayed
leftAside
ComputedRef<boolean>
Whether aside is positioned on the left
headers
Ref<OutlineItem[]>
Page outline/headers
hasLocalNav
ComputedRef<boolean>
Whether local navigation should be shown

Custom Theme Example

// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import CustomLayout from './CustomLayout.vue'
import './custom.css'

export default {
  extends: DefaultTheme,
  Layout: CustomLayout,
  enhanceApp({ app }) {
    // Register custom components
    app.component('MyComponent', MyComponent)
  }
}

Layout Slots

The default theme Layout component provides numerous slots for customization. See the Layout Slots documentation for a complete list.

Build docs developers (and LLMs) love