Usage of Client Config

You can make use of the client config file directly in your project, or specify the file path in your plugin or theme via clientConfigFile hook:

import { getDirname, path } from 'vuepress/utils'

const __dirname = getDirname(import.meta.url)

const pluginOrTheme = {
  clientConfigFile: path.resolve(__dirname, './path/to/clientConfig.ts'),
}

Inside the client config file, vuepress/client provides a helper function defineClientConfig to help you define the client config:

import { defineClientConfig } from 'vuepress/client'

export default defineClientConfig({
  enhance({ app, router, siteData }) {},
  setup() {},
  layouts: {},
  rootComponents: [],
})

enhance

The enhance function could be either synchronous or asynchronous. It accepts a context param with following properties:

The enhance function will be invoked after the client app is created. It's possible to implement any enhancements to the Vue application.

Register Vue Components

You can register global Vue components via the app.componentopen in new window method:

import { defineClientConfig } from 'vuepress/client'
import MyComponent from './MyComponent.vue'

export default defineClientConfig({
  enhance({ app }) {
    app.component('MyComponent', MyComponent)
  },
})

Use Non-SSR-Friendly Features

VuePress will generate a SSR application to pre-render pages during build. Generally speaking, if a code snippet is using Browser / DOM APIs before client app is mounted, we call it non-SSR-friendly.

We already provides a ClientOnly component to wrap non-SSR-friendly content.

In the enhance function, you can make use of the __VUEPRESS_SSR__ flag for that purpose.

import { defineClientConfig } from 'vuepress/client'

export default defineClientConfig({
  async enhance() {
    if (!__VUEPRESS_SSR__) {
      const nonSsrFriendlyModule = await import('non-ssr-friendly-module')
      // ...
    }
  },
})

Use Router Methods

You can make use of the Router Methodsopen in new window that provided by vue-router. For example, add navigation guard:

import { defineClientConfig } from 'vuepress/client'

export default defineClientConfig({
  enhance({ router }) {
    router.beforeEach((to) => {
      console.log('before navigation')
    })

    router.afterEach((to) => {
      console.log('after navigation')
    })
  },
})

WARNING

It's not recommended to use addRoute method to add dynamic routes here, because those routes will NOT be pre-rendered in build mode.

But you can still do that if you understand the drawback.

setup

The setup function would be invoked inside the setupopen in new window hook of the client vue app.

Use Composition API

You can take the setup function as part of the setupopen in new window hook of the root component. Thus, all composition APIs are available here.

import { provide, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { defineClientConfig } from 'vuepress/client'

export default defineClientConfig({
  setup() {
    // get the current route location
    const route = useRoute()
    // get the vue-router instance
    const router = useRouter()
    // provide a value that can be injected by layouts, pages and other components
    const count = ref(0)
    provide('count', count)
  },
})

Use Non-SSR-Friendly Features

In the setup function, the __VUEPRESS_SSR__ flag is also available.

Another way to use non-ssr-friendly features is to put them inside the onMountedopen in new window hook:

import { defineClientConfig } from 'vuepress/client'
import { onMounted } from 'vue'

export default defineClientConfig({
  setup() {
    onMounted(() => {
      // use DOM API after mounted
      document.querySelector('#app')
    })
  },
})

layouts

The layouts options is to set layout components. After layout components are registered here, users can use it via layout frontmatter.

import { defineClientConfig } from 'vuepress/client'
import MyLayout from './layouts/MyLayout.vue'

export default defineClientConfig({
  layouts: {
    MyLayout,
  },
})

rootComponents

The rootComponents is a components array to be placed directly into the root node of the client vue app.

Typical usage of this option is to put some global UI components, like global popup or so:

import { defineClientConfig } from 'vuepress/client'
import GlobalPopup from './components/GlobalPopup.vue'

export default defineClientConfig({
  rootComponents: [GlobalPopup],
})