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
The root layout component for your theme
enhanceApp
(ctx: EnhanceAppContext) => Awaitable<void>
Function to enhance the Vue app instance
Another theme to extend from
Theme-level setup function (deprecated - use Layout component setup instead)
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:
Register Components
Add Plugins
Router Hooks
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
In Markdown:
# API < Badge type = "info" text = "v2.0+" />
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
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
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 >
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 >
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
VPSocialLinks
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 >
VPSocialLink
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
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
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 >
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 ()
Whether the current page is the home page
Whether sidebar should be displayed
Whether sidebar is enabled at current viewport
Whether aside/outline should be displayed
Whether aside is positioned on the left
Whether local navigation should be shown
Custom Theme Example
Extending Default Theme
Custom Layout
Completely Custom Theme
// .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.