React Native SDK

Add the provider, identify your users, and show flows in your React Native app.

Last reviewed

React Native SDK

Use the React Native SDK to show getuserfeedback.com flows — surveys, forms, and in-app messages — inside your mobile app.

1. Install

Install the SDK and its WebView peer dependency:

npm install @getuserfeedback/react-native react-native-webview

The SDK requires React 18 or later, React Native 0.73 or later, and react-native-webview 13 or later.

If you use Expo, let Expo choose the compatible WebView version:

npm install @getuserfeedback/react-nativenpx expo install react-native-webview

2. Add the provider

Wrap your app with GetUserFeedbackProvider. This starts the client and makes it available to hooks below the provider.

TypeScriptapp.tsx
import { GetUserFeedbackProvider } from "@getuserfeedback/react-native";export function App() {return (<GetUserFeedbackProvider clientOptions={{ apiKey: "YOUR_API_KEY" }}><AppRoutes /></GetUserFeedbackProvider>);}

Find your Public API key in Widget settings.

Where you mount the provider controls who can receive a flow:

  • Wrap your whole app to include signed-out visitors and public screens.
  • Mount it below your auth provider if flows should only reach signed-in users.

You're live

Flows configured for automatic Widget delivery now appear based on the targeting rules you set in the dashboard. Nothing appears until you publish a flow whose targeting matches the current person or app state.

3. Identify signed-in users

Identify people after sign-in so you can target by traits and connect responses to the right person. Render this component after your app has an authenticated user object.

TypeScriptidentify-user.tsx
import { useEffect } from "react";import { useGetUserFeedback } from "@getuserfeedback/react-native";export function IdentifyUser({user,}: {user: { id: string; email: string; plan: string };}) {const client = useGetUserFeedback();const { email, id, plan } = user;useEffect(() => {void client.identify(id, { email, plan }).catch((error) => console.error("Unable to identify user", error));}, [client, email, id, plan]);return null;}

Anonymous flows work without this step. Await client.reset() as part of your logout flow so the previous person's identity does not carry over. See Personalization for targeting and identity patterns.

Open a flow from your app

To open a flow from a button or another app action, set its delivery channel to Widget and its delivery method to On-demand, then publish it. Copy its flow ID from the flow settings and pass that ID to client.flow():

import { Button } from "react-native";import { useGetUserFeedback } from "@getuserfeedback/react-native";export function FeedbackButton() {const client = useGetUserFeedback();return (<Buttontitle="Send feedback"onPress={() => {void client.flow("YOUR_FLOW_ID").open().catch((error) => console.error("Unable to open feedback", error));}}/>);}

Keep the flow object when several actions belong to the same flow lifecycle. prefetch() loads the flow's network resources, while prerender() also warms its UI so it can appear faster. These methods return promises: await them or attach a rejection handler.

Call flow.close() to close that flow. Use client.close() only when you want to close every open flow for this provider. See Open Widget flows from code for more on on-demand delivery.

Track product events

Send events that your targeting rules use:

import { Button } from "react-native";import { useGetUserFeedback } from "@getuserfeedback/react-native";export function CheckoutButton() {const client = useGetUserFeedback();return (<Buttontitle="Start checkout"onPress={() => {void client.track("Checkout Started", {plan: "pro",source: "billing_screen",}).catch((error) => console.error("Unable to track event", error));}}/>);}

See Events for event naming and payload guidance.

If nothing appears

Check these first:

  1. GetUserFeedbackProvider is mounted above the component using the hook.
  2. The API key comes from the same workspace as the flow.
  3. The flow is published. For automatic delivery, its targeting matches the current person.
  4. An identity-required flow receives identify() before it opens.
  5. A manually opened flow uses Widget and On-demand delivery.
  6. react-native-webview is installed in the app build.

During integration, use onError to send SDK errors to your logger. This observer does not consume rejected command promises, so continue to await or catch commands where you call them.

<GetUserFeedbackProviderclientOptions={{ apiKey: "YOUR_API_KEY" }}onError={(error) => console.error("Feedback SDK error", error)}><AppRoutes /></GetUserFeedbackProvider>

Next steps