--- name: extending-vitepress-default-theme description: Customize CSS variables, use layout slots, register global components, and override theme fonts --- # Extending Default Theme Customize the default theme through CSS, slots, and Vue components. ## Theme Entry File Create `.vitepress/theme/index.ts` to extend the default theme: ```ts // .vitepress/theme/index.ts import DefaultTheme from 'vitepress/theme' import './custom.css' export default DefaultTheme ``` ## CSS Variables Override root CSS variables: ```css /* .vitepress/theme/custom.css */ :root { /* Brand colors */ --vp-c-brand-1: #646cff; --vp-c-brand-2: #747bff; --vp-c-brand-3: #9499ff; /* Backgrounds */ --vp-c-bg: #ffffff; --vp-c-bg-soft: #f6f6f7; /* Text */ --vp-c-text-1: #213547; --vp-c-text-2: #476582; } .dark { --vp-c-brand-1: #747bff; --vp-c-bg: #1a1a1a; } ``` See [all CSS variables](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css). ## Home Hero Customization ```css :root { /* Gradient name color */ --vp-home-hero-name-color: transparent; --vp-home-hero-name-background: linear-gradient(120deg, #bd34fe, #41d1ff); /* Hero image glow */ --vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%); --vp-home-hero-image-filter: blur(44px); } ``` ## Custom Fonts Remove Inter font and use your own: ```ts // .vitepress/theme/index.ts import DefaultTheme from 'vitepress/theme-without-fonts' import './fonts.css' export default DefaultTheme ``` ```css /* .vitepress/theme/fonts.css */ @font-face { font-family: 'MyFont'; src: url('/fonts/myfont.woff2') format('woff2'); } :root { --vp-font-family-base: 'MyFont', sans-serif; --vp-font-family-mono: 'Fira Code', monospace; } ``` Preload fonts in config: ```ts // .vitepress/config.ts export default { transformHead({ assets }) { const fontFile = assets.find(file => /myfont\.[\w-]+\.woff2/.test(file)) if (fontFile) { return [ ['link', { rel: 'preload', href: fontFile, as: 'font', type: 'font/woff2', crossorigin: '' }] ] } } } ``` ## Global Components Register components available in all markdown: ```ts // .vitepress/theme/index.ts import DefaultTheme from 'vitepress/theme' import MyComponent from './components/MyComponent.vue' export default { extends: DefaultTheme, enhanceApp({ app }) { app.component('MyComponent', MyComponent) } } ``` Use in markdown: ```md ``` ## Layout Slots Inject content into specific locations: ```ts // .vitepress/theme/index.ts import DefaultTheme from 'vitepress/theme' import MyLayout from './MyLayout.vue' export default { extends: DefaultTheme, Layout: MyLayout } ``` ```vue ``` ### Available Slots **Doc layout (`layout: doc`):** - `doc-top`, `doc-bottom` - `doc-before`, `doc-after` - `doc-footer-before` - `sidebar-nav-before`, `sidebar-nav-after` - `aside-top`, `aside-bottom` - `aside-outline-before`, `aside-outline-after` - `aside-ads-before`, `aside-ads-after` **Home layout (`layout: home`):** - `home-hero-before`, `home-hero-after` - `home-hero-info-before`, `home-hero-info`, `home-hero-info-after` - `home-hero-actions-after`, `home-hero-image` - `home-features-before`, `home-features-after` **Page layout (`layout: page`):** - `page-top`, `page-bottom` **Always available:** - `layout-top`, `layout-bottom` - `nav-bar-title-before`, `nav-bar-title-after` - `nav-bar-content-before`, `nav-bar-content-after` - `not-found` (404 page) ## Using Render Functions Alternative to template slots: ```ts // .vitepress/theme/index.ts import { h } from 'vue' import DefaultTheme from 'vitepress/theme' import MyComponent from './MyComponent.vue' export default { extends: DefaultTheme, Layout() { return h(DefaultTheme.Layout, null, { 'aside-outline-before': () => h(MyComponent) }) } } ``` ## Override Internal Components Replace default theme components with Vite aliases: ```ts // .vitepress/config.ts import { fileURLToPath, URL } from 'node:url' export default { vite: { resolve: { alias: [ { find: /^.*\/VPNavBar\.vue$/, replacement: fileURLToPath( new URL('./theme/components/CustomNavBar.vue', import.meta.url) ) } ] } } } ``` ## View Transitions Custom dark mode toggle animation: ```vue ``` ## Key Points - Import `vitepress/theme-without-fonts` to use custom fonts - Use layout slots to inject content without overriding components - Global components are registered in `enhanceApp` - Override CSS variables for theming - Use Vite aliases to replace internal components