UpVoiced Docs · Widget
JavaScript API reference
w.js replaces window.UpVoiced with the API below. Calls made earlier through the queue stub run in order as soon as it loads. The API never throws into your page and never exposes the session token.
Methods
identify
UpVoiced.identify({ token }) / UpVoiced.identify(null)Signs in the person signed in to your app with a token from your server, or signs out with null. Returns a promise that never rejects: { ok: true, user } or { ok: false, error }. See Identify signed-in users.
open
UpVoiced.open(tab?)Opens the panel, on 'feedback', 'roadmap' or 'whats-new' when that tab is enabled (otherwise the first tab).
close
UpVoiced.close()Closes the panel and returns focus to where it was. Does nothing for an inline (data-mount) widget.
config
UpVoiced.config({ position, launcher, theme, accent, radius, offset, tabs })Overrides your settings and the script attributes on this page. Each call merges with the previous ones; invalid values are ignored. tabs narrows the enabled tabs, never adds one.
on
UpVoiced.on(event, listener)Listens to ready, open, close, identify and unread. A listener added after ready has fired is called once right away. Errors thrown by listeners are caught.
track
UpVoiced.track(event, properties?)Reserved for in-app surveys; accepted and recorded, but it sends nothing yet.
Precedence, lowest first: your dashboard settings, thescript tag attributes, then config().
Properties
UpVoiced.user: the identified user (id,name,email,avatarUrl) ornull.UpVoiced.workspace: the slug fromdata-workspace.UpVoiced.version: the loader version.UpVoiced.calls: the commands received so far, for debugging; identify arguments are shown as[redacted].
Events
| Event | Payload | When |
|---|---|---|
ready | none | The launcher (or inline panel) is on the page. Fires once. |
open | { tab } | The panel opened (tab is the requested tab or null). |
close | none | The panel closed. |
identify | { ok, user } or { ok, error } | An identify settled, or the session expired (error: "session_expired"). |
unread | { changelog, statusChanges } | Unread state for the signed-in user changed (launcher dot). |
Examples
// Your own "Feedback" button instead of the launcher (script tag: data-launcher="none").
document.querySelector('#feedback-button').addEventListener('click', function () {
UpVoiced.open();
});
// Jump to the roadmap from a "What's planned?" link.
UpVoiced.open('roadmap');
// Dark pages: follow your app's theme switch.
UpVoiced.config({ theme: 'dark' });
// Only the Feedback tab on the checkout page (never adds a tab you turned off).
UpVoiced.config({ tabs: ['feedback'] });
// Show your own badge when there is news for the signed-in user.
UpVoiced.on('unread', function (unread) {
badge.hidden = !(unread.changelog || unread.statusChanges > 0);
});TypeScript
// upvoiced.d.ts: types for window.UpVoiced (copy into your project).
export type UpVoicedTab = 'feedback' | 'roadmap' | 'whats-new';
export interface UpVoicedUser {
id: string;
name: string | null;
email: string | null;
avatarUrl: string | null;
}
export type UpVoicedIdentifyResult =
| { ok: true; user: UpVoicedUser | null }
| { ok: false; error: string };
export interface UpVoicedConfig {
position?: 'bottom-right' | 'bottom-left' | 'right-middle' | 'left-middle';
launcher?: 'icon' | 'pill' | 'tab' | 'none';
theme?: 'light' | 'dark' | 'auto';
accent?: string; // #rrggbb
radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
offset?: number | string | { x: number; y: number }; // px, 0–200
tabs?: UpVoicedTab[];
}
export interface UpVoicedEvents {
ready: undefined;
open: { tab: UpVoicedTab | null };
close: undefined;
identify: UpVoicedIdentifyResult;
unread: { changelog: boolean; statusChanges: number };
}
export interface UpVoicedApi {
readonly version: string;
readonly workspace: string;
readonly user: UpVoicedUser | null;
identify(input: { token: string } | null): Promise<UpVoicedIdentifyResult>;
config(options: UpVoicedConfig): void;
open(tab?: UpVoicedTab): void;
close(): void;
on<E extends keyof UpVoicedEvents>(event: E, listener: (payload: UpVoicedEvents[E]) => void): void;
track(event: string, properties?: Record<string, unknown>): void;
}
declare global {
interface Window {
UpVoiced?: UpVoicedApi;
}
}