JavaScript SDK reference
Reference for @getuserfeedback/sdk clients, flow handles, events, and configuration.
- Last reviewed
JavaScript SDK reference
Everything revolves around one client created with createClient(). If you
haven't set up yet, start with the
JavaScript SDK guide.
createClient(options)
Create a single client and reuse it across your app. Calling createClient
again with the same API key and equivalent client configuration returns the
same instance.
import { createClient } from "@getuserfeedback/sdk";const client = createClient({ apiKey: "YOUR_API_KEY" });Options
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | required | Your project API key. |
colorScheme | "light" | "dark" | "system" | { autoDetectColorScheme: string[] } | auto-detect | Color scheme. See Dark mode. |
defaultConsent | "granted" | "pending" | "denied" | "revoked" | GrantScope[] | "granted" | Initial consent state. See Privacy & consent. |
disableAutoLoad | boolean | false | When true, call client.load() manually before using the widget. |
disableTelemetry | boolean | false | Disables anonymous performance telemetry. Does not affect user analytics. |
enableDebug | boolean | string | string[] | false | Enable debug logging globally or for selected namespaces. |
flags | Record<string, AppEventFlagValue> | AppEventFlag[] | none | Your app's feature flag evaluations. Used by rolling theme updates. |
capabilities | Array<string | AppEventCapability> | none | What the current app version can support. Used by capability conditions. |
links | LinksConfig | none | Synchronously route authored HTTP(S) links in the host app. |
actions | ActionsConfig | ActionRegistration[] | none | Static custom actions and the legacy browser URL override. Prefer ActionsConfig for custom actions. |
Manual loading
When disableAutoLoad is true, provide the initial color scheme, consent as
defaultConsent, and capabilities in createClient(), then call
client.load() when you are ready to start the widget. Configure auth and make
other dynamic configuration changes after load(). A configure() call before
load() resolves without applying its update. Call load() before commands
that require the widget, such as opening a flow or tracking an event.
Links (links)
Provide a synchronous router to claim every authored HTTP(S) link before the Loader's browser fallback:
const client = createClient({apiKey: "YOUR_API_KEY",links: {router: ({ url, target }) => {appRouter.navigate(url, target);},},});The router receives url and the authored target ("self" or "blank",
when available). It must claim the request synchronously and return undefined.
Throwing or returning a promise-like value is terminal failure and suppresses
browser fallback. Omit links to keep the default browser behavior. Router
presence is fixed after initialization, while calling createClient() again
for the same client may refresh the router function.
Actions (actions)
Register custom actions through actions. Definitions remain fixed after
loading starts, while the handler can be refreshed. See
Actions for setup and behavior.
Client methods
Identity
client.identify(userId, traits?, options?)— associate a user ID, traits, and optional external IDs with the current userclient.identify(traits, options?)— associate traits with the current userclient.identify(traits, undefined, options?)— three-argument form for call sites that keep options separateclient.reset()— clear identity and auth state on logout
Configuration
client.configure({ colorScheme?, consent?, auth?, capabilities? })— update settings at runtimeclient.load()— manually start the widget whendisableAutoLoadistrueclient.close()— close any open flow
See Capabilities for initialization and runtime update examples. The widget checks for newly eligible flows after capabilities change.
Flows
client.flow(flowId)— get a reusable flow handle (see below)client.flow(flowId).open(options?)— open a flowclient.flow(flowId).prefetch()— load flow resources over the networkclient.flow(flowId).prerender(options?)— warm up the UI before opening
Observation
client.track(eventName, properties?, options?)— track a product event with optional external IDsclient.page(name?, properties?, options?)— record a browser page or web location. See Events.client.graph.connect(relationship)— record that two product objects are connectedclient.graph.disconnect(relationship)— record that the connection endedclient.getFlowState()— get the current instance-level aggregate flow stateclient.subscribeFlowState(callback, options?)— watch instance-level aggregate flow state changesclient.onOpenRequested(callback)— observe explicit SDK and client-side targeting opens before the flow rendersclient.setDefaultContainerPolicy(policy)— control default container behavior
Events
Use client.track() for product actions and client.page() for browser page
or web locations. See Events for the shared argument
rules and examples.
Relationships
Use client.graph to record connections between users, accounts, workspaces,
projects, or other product objects. Each endpoint needs a collection key and a
stable ID.
const relationship = {from: { collection: "user", id: "user_123" },to: { collection: "account", id: "acct_456" },};await client.graph.connect(relationship);await client.graph.disconnect(relationship);These methods record ordinary analytics observations. A disconnect ends the
connection established by earlier observations; a later connect can establish
it again. Collection keys use lowercase kebab-case, such as user or
property-manager, and IDs must be nonblank. Invalid relationship properties
remain ordinary analytics events but do not update the graph. See
Groups for audience behavior and current limitations.
Flow state observation
Use flow state observation when your app needs to react to presentation state,
such as showing a host-owned container while a flow opens. FlowState contains
the latest known snapshot:
| Field | Type | Description |
|---|---|---|
isOpen | boolean | true when the flow is visible. |
isLoading | boolean | true after an open request while the flow is not visible yet. Prefetching or prerendering alone does not set this. |
width | number | undefined | Flow width in pixels when known. |
height | number | undefined | Flow height in pixels when known. |
client.getFlowState() and client.subscribeFlowState() use instance-level
aggregate state. This includes opens from flow handles and targeting, so it is
not limited to one flowId. For one specific flow, use the matching reusable
handle's getFlowState() and subscribeFlowState() methods below.
Subscription options
Both client.subscribeFlowState() and a flow handle's
subscribeFlowState() accept these optional settings:
| Option | Type | Default | Description |
|---|---|---|---|
emitInitial | boolean | true | Call the callback immediately with the current snapshot. Set to false to receive only later state changes. |
signal | AbortSignal | none | Automatically unsubscribe when the signal is aborted. |
The callback receives the current FlowState snapshot on each update.
Each subscription returns an unsubscribe function, () => void. Call it when
you no longer need updates; the returned function and signal can both stop
the same subscription.
Flow handle
client.flow(flowId) returns a reusable handle for one specific flow. Use it
when you want to prefetch, prerender, and open as part of one lifecycle.
Handle command promises
open(), prefetch(), prerender(), and close() return promises. Handle a
rejected command through the returned promise.
Await a command when its completion controls what happens next:
const flow = client.flow("YOUR_FLOW_ID");try {await flow.prefetch();await flow.prerender();await flow.open();} catch (error) {console.error("Unable to open feedback", error);}When you don't need to wait, handle the rejection explicitly:
void flow.open().catch((error) => {console.error("Unable to open feedback", error);});Don't leave a command promise unhandled. The same rule applies to the React SDK, which wraps this runtime.
Methods
open(options?)— open the flow (options includecontainer,metadata, andhideCloseButton)prefetch()— load resources over the networkprerender(options?)— warm up the UIclose()— close the flowsetContainer(element | null)— attach or detach a custom containergetFlowState()— get the latestFlowStatesnapshot for this flowsubscribeFlowState(callback, options?)— watch this flow's state changes; returns an unsubscribe function
See Open Widget flows from code for usage patterns, Response metadata for metadata examples, and Containers for custom container examples.