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.

TypeScriptapp.ts
import { createClient } from "@getuserfeedback/sdk";const client = createClient({ apiKey: "YOUR_API_KEY" });

Options

OptionTypeDefaultDescription
apiKeystringrequiredYour project API key.
colorScheme"light" | "dark" | "system" | { autoDetectColorScheme: string[] }auto-detectColor scheme. See Dark mode.
defaultConsent"granted" | "pending" | "denied" | "revoked" | GrantScope[]"granted"Initial consent state. See Privacy & consent.
disableAutoLoadbooleanfalseWhen true, call client.load() manually before using the widget.
disableTelemetrybooleanfalseDisables anonymous performance telemetry. Does not affect user analytics.
enableDebugboolean | string | string[]falseEnable debug logging globally or for selected namespaces.
flagsRecord<string, AppEventFlagValue> | AppEventFlag[]noneYour app's feature flag evaluations. Used by rolling theme updates.
capabilitiesArray<string | AppEventCapability>noneWhat the current app version can support. Used by capability conditions.
linksLinksConfignoneSynchronously route authored HTTP(S) links in the host app.
actionsActionsConfig | ActionRegistration[]noneStatic 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.

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 user
  • client.identify(traits, options?) — associate traits with the current user
  • client.identify(traits, undefined, options?) — three-argument form for call sites that keep options separate
  • client.reset() — clear identity and auth state on logout

Configuration

  • client.configure({ colorScheme?, consent?, auth?, capabilities? }) — update settings at runtime
  • client.load() — manually start the widget when disableAutoLoad is true
  • client.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 flow
  • client.flow(flowId).prefetch() — load flow resources over the network
  • client.flow(flowId).prerender(options?) — warm up the UI before opening

Observation

  • client.track(eventName, properties?, options?) — track a product event with optional external IDs
  • client.page(name?, properties?, options?) — record a browser page or web location. See Events.
  • client.graph.connect(relationship) — record that two product objects are connected
  • client.graph.disconnect(relationship) — record that the connection ended
  • client.getFlowState() — get the current instance-level aggregate flow state
  • client.subscribeFlowState(callback, options?) — watch instance-level aggregate flow state changes
  • client.onOpenRequested(callback) — observe explicit SDK and client-side targeting opens before the flow renders
  • client.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:

FieldTypeDescription
isOpenbooleantrue when the flow is visible.
isLoadingbooleantrue after an open request while the flow is not visible yet. Prefetching or prerendering alone does not set this.
widthnumber | undefinedFlow width in pixels when known.
heightnumber | undefinedFlow 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:

OptionTypeDefaultDescription
emitInitialbooleantrueCall the callback immediately with the current snapshot. Set to false to receive only later state changes.
signalAbortSignalnoneAutomatically 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 include container, metadata, and hideCloseButton)
  • prefetch() — load resources over the network
  • prerender(options?) — warm up the UI
  • close() — close the flow
  • setContainer(element | null) — attach or detach a custom container
  • getFlowState() — get the latest FlowState snapshot for this flow
  • subscribeFlowState(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.