Events

Track product actions, browser pages, and native application screens.

Last reviewed

Events

Use events to report product activity and locations to getuserfeedback.com. The client methods use the same properties and options shape, but each method describes a different kind of event:

  • track() records a product action, such as a checkout starting.
  • page() records a browser document or web location. Its name is optional; omitting it uses the current browser pathname, or / when there is no pathname.
  • screen() records a named application screen in a native app. Its name is required.

We recommend sending product events through a connected integration such as Segment when it already owns event delivery for your app. If client-side tracking fits your app better, call these methods directly.

page() and screen() are explicit calls. The SDKs do not automatically send these events when navigation changes unless you opt in to a React Native screen-tracking adapter below. Browser URL targeting still observes the current browser location automatically; that context is separate from a persisted page() event.

Examples

JavaScript SDK

TypeScriptevents.ts
import { createClient } from "@getuserfeedback/sdk";const client = createClient({ apiKey: "YOUR_API_KEY" });await client.track("Checkout Started", { plan: "pro" });await client.page("Billing");

React SDK

Call the methods from a component below GetUserFeedbackProvider:

TypeScriptevents.tsx
import { useEffect } from "react";import { useGetUserFeedback } from "@getuserfeedback/react";export function CheckoutButton() {const client = useGetUserFeedback();return (<buttontype="button"onClick={() => {void client.track("Checkout Started", { plan: "pro" }).catch((error) => console.error("Unable to track event", error));}}>Start checkout</button>);}function BillingPage() {const client = useGetUserFeedback();useEffect(() => {void client.page("Billing").catch((error) => console.error("Unable to record page", error));}, [client]);return null;}

React Native SDK

Call screen() when your app navigation changes:

TypeScriptevents.tsx
import { useEffect } from "react";import { useGetUserFeedback } from "@getuserfeedback/react-native";export function CheckoutScreen() {const client = useGetUserFeedback();useEffect(() => {void client.screen("Checkout").catch((error) => console.error("Unable to record screen", error));}, [client]);return null;}

React Native screen tracking

Screen tracking is opt-in. Mount the tracking hook below GetUserFeedbackProvider, then choose one path for your app's navigation:

React Navigation

Use the shipped adapter with the same ref you pass to NavigationContainer:

TypeScriptapp-navigation.tsx
import {NavigationContainer,useNavigationContainerRef,} from "@react-navigation/native";import { useReactNavigationScreenTracking } from"@getuserfeedback/react-native/react-navigation";export function AppNavigation() {const navigationRef = useNavigationContainerRef();useReactNavigationScreenTracking(navigationRef);return (<NavigationContainer ref={navigationRef}><AppRoutes /></NavigationContainer>);}

Expo Router

Render a tracker below GetUserFeedbackProvider, for example from your root layout:

TypeScriptscreen-tracking.tsx
import { usePathname } from "expo-router";import { useExpoRouterScreenTracking } from"@getuserfeedback/react-native/expo-router";export function ScreenTracking() {const pathname = usePathname();useExpoRouterScreenTracking(pathname);return null;}

Both adapters accept optional options for mapping route data to screen names and handling tracking errors.

Any other router

Call client.screen() from your router's current-screen state. Pass a stable key for the active route occurrence so repeated notifications and React Strict Mode do not record the same occurrence twice:

TypeScriptscreen-tracker.tsx
import { useEffect, useRef } from "react";import { useGetUserFeedback } from "@getuserfeedback/react-native";export function ScreenTracker({routeKey,screenName,}: {routeKey: string;screenName: string;}) {const client = useGetUserFeedback();const lastRoute = useRef({ client, routeKey: null as string | null });useEffect(() => {if (lastRoute.current.client === client &&lastRoute.current.routeKey === routeKey) {return;}lastRoute.current = { client, routeKey };const reportScreen = async () => {try {await client.screen(screenName);} catch (error) {console.error("Unable to record screen", error);}};void reportScreen();}, [client, routeKey, screenName]);return null;}

Use one tracking path for a navigation tree. All three paths record a screen when the active route changes.

Shared call shape

MethodUse it forName argument
track(eventName, properties?, options?)A product actionRequired and trimmed to 1-255 characters.
page(name?, properties?, options?)A browser page or web locationOptional. A supplied name is trimmed to 1-255 characters; the browser pathname is used when omitted.
screen(name, properties?, options?)A native application screenRequired and trimmed to 1-255 characters.

Names reserved for getuserfeedback.com system events, such as Flow Viewed, cannot be used for customer events.

Use page() in the JavaScript and React SDKs. Use screen() in the React Native SDK. Call the method from your router or navigation integration when the location changes. This reference covers both direct calls and the opt-in React Native screen-tracking adapters.

Properties and options

The event methods accept the same optional properties and options values:

FieldRequiredShape
propertiesNoAn object with string keys and JSON-compatible values.
options.messageIdNoA caller-supplied, non-empty string up to 255 characters.
options.externalIdsNoUp to 20 Segment-compatible external user IDs.

Supported property values are strings, numbers, booleans, null, arrays of supported values, and nested objects with string keys. Send dates as ISO 8601 strings. Convert functions, class instances, DOM nodes, undefined, and circular objects before calling an event method.

Use externalIds for an identifier from another system. Each entry uses an ID, type, collection: "users", and encoding: "none":

client.track("Checkout Started",{ plan: "pro" },{externalIds: [{id: "gid://shopify/Customer/123",type: "shopify_customer_id",collection: "users",encoding: "none",},],},);

External IDs help match profiles, but they are not traits or event properties. Do not put Segment-shaped external IDs inside properties.

The id must be nonblank. The type must start with a lowercase letter or number and can contain lowercase letters, numbers, underscores, dots, and hyphens.

messageId is the identity of one event occurrence. Generate a new value for each new occurrence and preserve it when that same occurrence is passed through another delivery path:

function reportCheckoutStarted(event: {messageId: string;orderId: string;}) {return client.track("Checkout Started",{ orderId: event.orderId },{ messageId: event.messageId },);}

getuserfeedback.com preserves messageId unchanged. It is not a command idempotency key and does not promise deduplication across delivery channels.

Event names

Name events after what happened or what location was reported:

  • track("Checkout Started") describes a product action.
  • page("Billing") describes a browser page or web location.
  • screen("Checkout") describes a native application screen.

You can call event methods before or after login. When the same person is later identified, Identity resolution can merge their events into a single profile.

When defaultConsent is "pending" or analytics consent is denied, client-side event delivery follows the widget consent state.

Flow Action Succeeded

For supported Widget actions, getuserfeedback.com records Flow Action Succeeded when a registered handler returns or resolves successfully, or when a supported browser navigation is accepted.

Flow Action Succeeded does not confirm that a destination loaded or that an external effect completed after the handler returned. Browser reporting is best effort, so a missing event does not prove that the action did not run or succeed.

See Actions for the shared custom action contract.

The event includes these getuserfeedback.com-owned properties:

PropertyMeaning
gx_event_schemaStable event identity: gx_flow_action_succeeded.
gx_event_schema_versionContract version. The current version is 1.
gx_flow_idFlow containing the action.
gx_flow_version_idExact Flow version containing the action.
gx_flow_version_numberPublished version number.
gx_flow_run_idFlow run that invoked the action.
gx_flow_surfaceSurface where the Flow ran.
gx_action_idStable placement of this action in the authored Flow.
gx_action_invocation_idLogical invocation that produced this success.
gx_action_keyAction definition key.
gx_action_versionAction definition version.
gx_action_kindAction kind, such as runtime-action or navigation-action.