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
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:
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:
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:
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:
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:
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
| Method | Use it for | Name argument |
|---|---|---|
track(eventName, properties?, options?) | A product action | Required and trimmed to 1-255 characters. |
page(name?, properties?, options?) | A browser page or web location | Optional. A supplied name is trimmed to 1-255 characters; the browser pathname is used when omitted. |
screen(name, properties?, options?) | A native application screen | Required 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:
| Field | Required | Shape |
|---|---|---|
properties | No | An object with string keys and JSON-compatible values. |
options.messageId | No | A caller-supplied, non-empty string up to 255 characters. |
options.externalIds | No | Up 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.
Identity and consent
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:
| Property | Meaning |
|---|---|
gx_event_schema | Stable event identity: gx_flow_action_succeeded. |
gx_event_schema_version | Contract version. The current version is 1. |
gx_flow_id | Flow containing the action. |
gx_flow_version_id | Exact Flow version containing the action. |
gx_flow_version_number | Published version number. |
gx_flow_run_id | Flow run that invoked the action. |
gx_flow_surface | Surface where the Flow ran. |
gx_action_id | Stable placement of this action in the authored Flow. |
gx_action_invocation_id | Logical invocation that produced this success. |
gx_action_key | Action definition key. |
gx_action_version | Action definition version. |
gx_action_kind | Action kind, such as runtime-action or navigation-action. |