How to use library with Web Components in Vitepress

195 Views Asked by At

Edited 2023-11-05: Added <ClientOnly/> to make the issue with the import more obvious. In response to @laplacetw's answer.

I have an existing library with Web Components (custom elements) which I'd like to use in Markdown files in Vitepress.

<script setup>
import 'my-library/my-button'
</setup>

# My button:

<ClientOnly>
<my-button></my-button>
</ClientOnly>

Everything works fine in dev mode, and the component renders correctly. But when I run the build, I get an error message:

ReferenceError: window is not defined

How can I tell Vitepress to treat the entire library as "Client Only" and not try to import it during server side rendering?

1

There are 1 best solutions below

1
On

Edited 2023-11-06:

As mentioned in #2367, the VitePress maintainer said we need to wrap custom elements with if (!import.meta.env.SSR) { ... } or if (inBrowser) { ... } :

// ref. https://vitepress.dev/guide/ssr-compat#conditional-import
    
// .vitepress/theme/index.js
/** @type {import('vitepress').Theme} */
export default {
  // ...
  async enhanceApp({ app }) {
    if (!import.meta.env.SSR) {
      const plugin = await import('plugin-that-access-window-on-import')
      app.use(plugin)
    }
  }
}

If you are using or demoing components that are not SSR-friendly (for example, contain custom directives), you can wrap them inside the built-in component :

<ClientOnly>
  <NonSSRFriendlyComponent />
</ClientOnly>

ref. https://vitepress.dev/guide/ssr-compat#clientonly