Skip to content

Custom Theme

Learn how to customize the VitePress theme to match your brand and design requirements.

Theme Structure

VitePress uses a theme system that allows you to customize the appearance and behavior of your documentation site. The default theme is located in node_modules/vitepress/dist/client/theme-default/.

Creating a Custom Theme

Basic Theme Setup

Create a theme directory structure:

.vitepress/
├── theme/
│   ├── index.ts
│   ├── style.css
│   └── components/
│       └── CustomComponent.vue
└── config.ts

Theme Entry Point

Create .vitepress/theme/index.ts:

ts
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import './style.css'

export default {
  ...DefaultTheme,
  Layout: () => {
    return h(DefaultTheme.Layout, null, {
      // Override slots here
    })
  },
  enhanceApp({ app }) {
    // Register custom components
    // app.component('MyComponent', MyComponent)
  }
}

Custom Styles

Add your custom CSS in .vitepress/theme/style.css:

css
:root {
  --vp-c-brand: #646cff;
  --vp-c-brand-light: #747bff;
  --vp-c-brand-dark: #535bf2;
}

/* Custom component styles */
.custom-component {
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  padding: 16px;
  margin: 16px 0;
}

Theme Customization Options

Colors

You can customize the color scheme by overriding CSS variables:

css
:root {
  /* Primary brand color */
  --vp-c-brand: #646cff;
  --vp-c-brand-light: #747bff;
  --vp-c-brand-dark: #535bf2;
  
  /* Background colors */
  --vp-c-bg: #ffffff;
  --vp-c-bg-alt: #f6f6f7;
  
  /* Text colors */
  --vp-c-text-1: #213547;
  --vp-c-text-2: #476582;
  --vp-c-text-3: #8f9198;
}

Typography

Customize fonts and typography:

css
:root {
  --vp-font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --vp-font-family-mono: 'Fira Code', 'Monaco', 'Consolas', monospace;
}

/* Custom heading styles */
h1 {
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1.2;
}

Layout Customization

Override layout components:

ts
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import CustomLayout from './CustomLayout.vue'

export default {
  ...DefaultTheme,
  Layout: () => h(CustomLayout)
}

Advanced Customization

Custom Components

Create reusable components:

vue
<!-- Example: .vitepress/theme/components/InfoBox.vue -->
<template>
  <div class="info-box" :class="type">
    <div class="icon">{{ icon }}</div>
    <div class="content">
      <h4>{{ title }}</h4>
      <p>{{ content }}</p>
    </div>
  </div>
</template>

<script setup>
defineProps({
  type: {
    type: String,
    default: 'info'
  },
  title: String,
  content: String,
  icon: String
})
</script>

<style scoped>
.info-box {
  display: flex;
  padding: 16px;
  border-radius: 8px;
  margin: 16px 0;
}

.info-box.info {
  background: #e3f2fd;
  border: 1px solid #2196f3;
}

.info-box.warning {
  background: #fff3e0;
  border: 1px solid #ff9800;
}
</style>

Global Components

Register components globally:

ts
// .vitepress/theme/index.ts
import InfoBox from './components/InfoBox.vue'

export default {
  ...DefaultTheme,
  enhanceApp({ app }) {
    app.component('InfoBox', InfoBox)
  }
}

Best Practices

Performance

  • Keep custom CSS minimal and focused
  • Use CSS variables for consistent theming
  • Avoid heavy JavaScript in theme components

Accessibility

  • Maintain proper color contrast ratios
  • Ensure keyboard navigation works
  • Test with screen readers

Responsive Design

  • Test on different screen sizes
  • Use relative units (rem, em, %)
  • Implement mobile-first design

Examples

Here's an example of how to use custom components in your theme:

js
// In your Vue component
<template>
  <div class="custom-info-box">
    <div class="icon">💡</div>
    <div class="content">
      <h4>Theme Customization</h4>
      <p>VitePress themes are highly customizable and can be extended with Vue components.</p>
    </div>
  </div>
</template>

This demonstrates how custom components can be integrated into your VitePress theme.