vitepress icon indicating copy to clipboard operation
vitepress copied to clipboard

Extending the vitepress theme

Open ghost opened this issue 4 years ago • 8 comments
trafficstars

I'd like to only have a custom NavLinks component while keeping the default vitepress theme. Next I looked at the NavBar although also my version doesn't override. Any help in the right direction would be great.

docs/.vitepress/config.js

import Theme from 'vitepress/theme'
import '../../assets/vars.css'
import NavBar from './Mynav.vue'

const MyTheme = {...Theme, Layout: {...Theme.Layout, NavBar}}

export default {
    ...MyTheme,
    NotFound: () => 'custom 404',
    enhanceApp({app, router, siteData}) {

    },
}

ghost avatar Feb 11 '21 12:02 ghost

Maybe this will help? https://github.com/vuejs/vitepress/issues/157

agritheory avatar Mar 10 '21 18:03 agritheory

The default theme is brilliant however I don't want to clone the entire theme into my working dir. I'm not sure how to extend simply the menu as I'd like to keep upstream changes without effort.

I moved on to creating my own theme however would love information on how to extend the default.

ghost avatar Mar 11 '21 07:03 ghost

@ahawkclint After some messing around, I'm in the same boat. I was hoping for a strategy from Vitepress where I could provide a variables file. While I think this is possible, it's not particularly clear to me how to do that. Did you make any progress?

agritheory avatar Mar 16 '21 15:03 agritheory

I follow the documentation for customizing the default theme Vue components but it's not working

. ├─ docs │ ├─ .vitepress │ │ ├─ theme │ │ │ └─ index.js │ │ └─ config.js │ └─ index.md └─ package.json

for example, I want to customize default LastUpdated.vue

so in the theme directory create another directory called components just like vitepress/dist/client/theme-default/

import DefaultTheme from 'vitepress/theme'
import LastUpdated from './components/LastUpdated.vue'

export default {
    ...DefaultTheme,
    LastUpdated,
    NotFound: () => 'custom 404',
    enhanceApp({ app, router, siteData }) {
        // app is the Vue 3 app instance from `createApp()`. router is VitePress'
        // custom router. `siteData`` is a `ref`` of current site-level metadata.
    }
}

sadeghbarati avatar May 19 '21 16:05 sadeghbarati

Hii, @sadeghbarati I think it'll work if you register the component properly

import DefaultTheme from 'vitepress/theme'
import LastUpdated from './components/LastUpdated.vue'

export default {
    ...DefaultTheme,
    NotFound: () => 'custom 404',
    enhanceApp({ app, router, siteData }) {
    app.component('last-updated',LastUpdated)
        // app is the Vue 3 app instance from `createApp()`. router is VitePress'
        // custom router. `siteData`` is a `ref`` of current site-level metadata.
    }
}

soulsam480 avatar Jun 14 '21 14:06 soulsam480

Registering the component globally did not work for me, but defining aliases in vite.config.js did:

const { defineConfig } = require('vite');
const path = require('path');

module.exports = defineConfig({
  resolve: {
    alias: {
      // Use my custom `NavBarTitle` component
      './NavBarTitle.vue': path.resolve(__dirname, '.vitepress/theme/components/NavBarTitle.vue'),
    },
  },
});

titouanmathis avatar Jan 07 '22 10:01 titouanmathis

This should be added to the interface of vitepress config so we can replace each default theme component.. this way we can replace a specific component and an plugin that adds darktheme can replace only the navbars component and a search plugin could change only the algolia component and so on.. multiple themes could be added chained and it would work as intended.

emersonbottero avatar Apr 20 '22 02:04 emersonbottero

One can do stuff like this for now:

https://github.com/antfu/vite-plugin-pwa/blob/ca8be823fecda2194b752ce50a8147d3de181ab1/docs/plugins/navbar.ts

// plugins/navbar.ts

import type { Plugin } from 'vite'

export default function NavbarFix(): Plugin {
  return {
    name: 'vitepress-sidebar-logo-fix',
    enforce: 'pre',
    transform(code, id) {
      if (id.includes('VPNavBarTitle.vue') && !id.endsWith('.css')) {
        return `override this component here. refer the above link for complete example`
      }
    }
  }
}

Then add a vite.config.ts at your docs root with this content:

import { defineConfig } from 'vite'
import NavbarFix from './plugins/navbar'

export default defineConfig({
  plugins: [NavbarFix()]
})

You'll need to change

id.includes('VPNavBarTitle.vue') && !id.endsWith('.css')

to

id.endsWith('VPNavBarTitle.vue')

after VitePress starts using Vite 3.

userquin avatar Jul 08 '22 07:07 userquin

Let's just document the alias method. I don't think there is any other way to properly replace the theme components.

brc-dd avatar Mar 10 '23 14:03 brc-dd