English · 中文
This is a demo for using naive-ui
in vitepress
with SSR enabled.
You can directly use the demo.
If you want to build your own demo from scratch, follow the next steps:
Make sure its version >=0.15.14
.
# npm
npm install --save-dev @css-render/vue3-ssr
# pnpm
pnpm install --save-dev @css-render/vue3-ssr
// .vitepress/theme/index.js
import { defineComponent, h, inject } from 'vue'
import DefaultTheme from 'vitepress/theme'
import { NConfigProvider } from 'naive-ui'
import { setup } from '@css-render/vue3-ssr'
import { useRoute } from 'vitepress'
const { Layout } = DefaultTheme
const CssRenderStyle = defineComponent({
setup() {
const collect = inject('css-render-collect')
return {
style: collect()
}
},
render() {
return h('css-render-style', {
innerHTML: this.style
})
}
})
const VitepressPath = defineComponent({
setup() {
const route = useRoute()
return () => {
return h('vitepress-path', null, [route.path])
}
}
})
const NaiveUIProvider = defineComponent({
render() {
return h(
NConfigProvider,
{ abstract: true, inlineThemeDisabled: true },
{
default: () => [
h(Layout, null, { default: this.$slots.default?.() }),
import.meta.env.SSR ? [h(CssRenderStyle), h(VitepressPath)] : null
]
}
)
}
})
export default {
extends: DefaultTheme,
Layout: NaiveUIProvider,
enhanceApp: ({ app }) => {
if (import.meta.env.SSR) {
const { collect } = setup(app)
app.provide('css-render-collect', collect)
}
}
}
import { defineConfig } from 'vitepress'
const fileAndStyles: Record<string, string> = {}
export default defineConfig({
// ...
vite: {
ssr: {
noExternal: ['naive-ui', 'date-fns', 'vueuc']
}
},
postRender(context) {
const styleRegex = /<css-render-style>((.|\s)+)<\/css-render-style>/
const vitepressPathRegex = /<vitepress-path>(.+)<\/vitepress-path>/
const style = styleRegex.exec(context.content)?.[1]
const vitepressPath = vitepressPathRegex.exec(context.content)?.[1]
if (vitepressPath && style) {
fileAndStyles[vitepressPath] = style
}
context.content = context.content.replace(styleRegex, '')
context.content = context.content.replace(vitepressPathRegex, '')
},
transformHtml(code, id) {
const html = id.split('/').pop()
if (!html) return
const style = fileAndStyles[`/${html}`]
if (style) {
return code.replace(/<\/head>/, style + '</head>')
}
}
})
...
<script setup>
import { NButton } from 'naive-ui'
</script>
<NButton>Hello World</NButton>
...