Init in an Application Route or an instance-initializer. Octane-friendly.
Ember apps are long-lived single pages, so the widget wants to boot once at app start. An instance-initializer is the cleanest hook: it runs after the app boots in the browser and gives you a place to tear down on teardown.
npm install @usero/sdkimport { initUseroFeedbackWidget } from '@usero/sdk'
export function initialize(appInstance) {
const widget = initUseroFeedbackWidget({ clientId: 'YOUR_CLIENT_ID' })
appInstance.reopen({ willDestroy() { widget.destroy(); this._super(...arguments) } })
}
export default { initialize }Replace YOUR_CLIENT_ID with the id from your Usero dashboard.
Built for Ember
It fires after the app instance is created in the browser, the right moment to mount a widget that should live for the whole session.
The vanilla SDK is plain JS, so it goes straight into your app tree. There is no ember-usero addon to keep in sync with Ember releases.
Instance-initializers predate Octane and still work in it. Glimmer components and tracked properties never interact with the widget.
Hooking willDestroy means FastBoot reboots and tests that recreate the app instance do not leak triggers into the DOM.
Productboard expects a hosted portal page. The vanilla SDK is a 12kb script that sits on top of your existing Ember UI.
FAQ
Instance-initializer. A plain initializer runs during FastBoot SSR too, where window does not exist. The instance variant runs per app instance, which in the browser is what you want.
No, and it is not needed. The vanilla SDK is a single import and a single call, which is less surface than an addon would add.
Keep the init in an instance-initializer and guard with a typeof window check if you render server-side. The SDK reads window, so it must only run client-side.
At the end of document.body, outside your Ember application root, so the Glimmer rendering layer never touches it.
Free tier. No credit card. Two-minute install. Cancel by deleting two lines of code.
Install guides