Custom Theme
Learn how to create and customize themes in VitePress.
Theme Structure
Basic Theme Setup
Create a custom theme by extending the default theme:
javascript
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import './custom.css'
export default {
extends: DefaultTheme,
enhanceApp({ app, router, siteData }) {
// App-level enhancements
}
}
Theme Directory Structure
.vitepress/
└── theme/
├── index.js # Theme entry
├── custom.css # Custom styles
├── components/ # Custom components
│ ├── MyComponent.vue
│ └── CustomLayout.vue
└── layouts/ # Custom layouts
└── MyLayout.vue
Customizing Styles
CSS Variables
Override default theme variables:
css
/* .vitepress/theme/custom.css */
:root {
--vp-c-brand-1: #646cff;
--vp-c-brand-2: #747bff;
--vp-c-brand-3: #9499ff;
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: linear-gradient(120deg, #bd34fe 30%, #41d1ff);
}
Component Styling
Style specific components:
css
.VPNavBar {
background-color: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
}
.VPSidebar {
border-right: 1px solid var(--vp-c-divider);
}
.VPContent {
max-width: 1200px;
}
Custom Components
Global Components
Register components globally:
javascript
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import MyComponent from './components/MyComponent.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('MyComponent', MyComponent)
}
}
Layout Components
Create custom layout components:
vue
<!-- .vitepress/theme/components/CustomLayout.vue -->
<template>
<Layout>
<template #nav-bar-title-after>
<span class="custom-badge">Beta</span>
</template>
<template #sidebar-nav-before>
<div class="custom-sidebar-header">
<h3>Quick Links</h3>
</div>
</template>
</Layout>
</template>
<script setup>
import DefaultTheme from 'vitepress/theme'
const { Layout } = DefaultTheme
</script>
Layout Customization
Custom Layouts
Create completely custom layouts:
vue
<!-- .vitepress/theme/layouts/CustomHome.vue -->
<template>
<div class="custom-home">
<header class="hero">
<h1>{{ $site.title }}</h1>
<p>{{ $site.description }}</p>
</header>
<main class="content">
<Content />
</main>
<footer class="footer">
<p>© 2024 My Site</p>
</footer>
</div>
</template>
<script setup>
import { useData } from 'vitepress'
const { site } = useData()
</script>
Layout Slots
Use available layout slots:
javascript
// Available slots in default theme
- nav-bar-title-before
- nav-bar-title-after
- nav-bar-content-before
- nav-bar-content-after
- nav-screen-content-before
- nav-screen-content-after
- sidebar-nav-before
- sidebar-nav-after
- page-top
- page-bottom
- not-found
- home-hero-before
- home-hero-info
- home-hero-actions
- home-hero-after
- home-features-before
- home-features-after
- doc-footer-before
- doc-before
- doc-after
- aside-top
- aside-bottom
- aside-outline-before
- aside-outline-after
- aside-ads-before
- aside-ads-after
Advanced Customization
Theme Configuration
Add theme-specific configuration:
javascript
// .vitepress/config.js
export default {
themeConfig: {
// Custom theme options
customOption: 'value',
// Override default theme config
nav: [...],
sidebar: {...}
}
}
Plugin Integration
Integrate with Vite plugins:
javascript
// .vitepress/config.js
import { defineConfig } from 'vitepress'
export default defineConfig({
vite: {
plugins: [
// Add Vite plugins
]
}
})
Theme Distribution
Package Structure
Structure for distributing themes:
my-vitepress-theme/
├── package.json
├── index.js
├── styles/
│ └── vars.css
├── components/
│ └── MyComponent.vue
└── layouts/
└── Layout.vue
Package Configuration
json
{
"name": "my-vitepress-theme",
"version": "1.0.0",
"main": "index.js",
"peerDependencies": {
"vitepress": "^1.0.0"
}
}
Theme Entry Point
javascript
// index.js
import DefaultTheme from 'vitepress/theme'
import './styles/vars.css'
export default {
extends: DefaultTheme,
// Theme customizations
}
Best Practices
Performance
- Minimize CSS bundle size
- Use CSS variables for theming
- Optimize component loading
- Implement proper caching
Accessibility
- Maintain proper contrast ratios
- Ensure keyboard navigation
- Use semantic HTML
- Test with screen readers
Maintainability
- Follow consistent naming conventions
- Document theme customizations
- Use TypeScript for better DX
- Implement proper testing