Init from the theme enhanceApp hook. Vue-powered, SSR-safe.
VitePress builds on Vue and Vite, and its theme has an enhanceApp hook that runs at app setup. Guard the widget init with an import.meta.env.SSR check so it boots in the browser only, then it covers every docs page.
npm install @usero/sdkimport DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
enhanceApp() {
if (import.meta.env.SSR) return
import('@usero/sdk').then(({ initUseroFeedbackWidget }) => {
initUseroFeedbackWidget({ clientId: 'YOUR_CLIENT_ID' })
})
},
}Replace YOUR_CLIENT_ID with the id from your Usero dashboard.
Built for VitePress
VitePress themes export enhanceApp, which runs once when the app is created. It is the idiomatic place to bootstrap a global like the widget.
enhanceApp also runs during VitePress static generation. The import.meta.env.SSR check keeps the browser-only widget code out of the server pass.
Importing the SDK lazily inside the browser branch means the server build never even parses it, avoiding any window reference at build time.
VitePress is Vue, but the widget is vanilla DOM. You do not register a Vue component, just call init from the theme hook.
Frill's iframe is heavy for a docs site. The vanilla SDK is a single dynamic import that loads only in the browser.
FAQ
In .vitepress/theme/index.js, inside the enhanceApp hook, behind an import.meta.env.SSR guard so it runs only in the browser.
enhanceApp runs during static generation too. The widget reads window, so the SSR guard prevents it from executing in the server build.
No. Although VitePress is Vue-based, the widget is vanilla DOM. Calling initUseroFeedbackWidget from enhanceApp is all you need.
Yes. enhanceApp runs once at app setup, so the widget is created a single time and survives client-side navigation between docs.
Free tier. No credit card. Two-minute install. Cancel by deleting two lines of code.
Install guides