@getuserfeedback/react-native
v1.3.9
Published
getuserfeedback React Native SDK
Maintainers
Readme
@getuserfeedback/react-native
React Native bindings for getuserfeedback.
This package hosts the existing getuserfeedback WebView runtime from React Native and exposes a provider/hook API for enqueueing widget commands from non-ejected Expo or React Native apps.
Install
npm install @getuserfeedback/react-native react-native-webviewRequires React, React Native, and react-native-webview.
API
GetUserFeedbackProvideruseGetUserFeedbackWidgetHostuseGetUserFeedbackNative
import {
GetUserFeedbackProvider,
useGetUserFeedback,
} from "@getuserfeedback/react-native";
function FeedbackActions() {
const feedback = useGetUserFeedback();
return (
<Button
title="Send feedback"
onPress={() => {
void feedback.open("flow_123");
}}
/>
);
}
export function App() {
return (
<GetUserFeedbackProvider
initOptions={{ apiKey: "YOUR_API_KEY" }}
loaderUrl="https://cdn.example.com/loader.js"
>
<FeedbackActions />
</GetUserFeedbackProvider>
);
}GetUserFeedbackProvider renders WidgetHost internally, auto-enqueues init, measures the React Native window for the hosted WebView viewport, shows the hosted WebView inside a native bottom sheet while a flow is loading or open, and resolves command promises when the WebView transport reports command settlement. Pass either loaderUrl or a custom WebView source so the hosted WebView has a loader runtime to execute commands. Use onCommandError to receive automatic setup failures from init or configure.
WidgetHost remains exported for advanced hosts that need direct WebView control.
The host message types are re-exported from @getuserfeedback/protocol/webview-transport through package-owned aliases so the React Native package stays aligned with the shared WebView transport contract.
Local Expo smoke test
Use the repo sandbox when testing a non-ejected Expo app against the local loader/core/API stack:
bun run start:sandboxCreate a React Native manifest:
curl -sS -X POST http://127.0.0.1:3710/api/sandbox/react-native-flow-assignmentFor a physical device, use an address the device can reach:
curl -sS -X POST "http://127.0.0.1:3710/api/sandbox/react-native-flow-assignment?publicHost=192.168.1.10"Then pass manifest.initOptions and manifest.loaderUrl to the provider:
import {
type GetUserFeedbackProviderProps,
GetUserFeedbackProvider,
useGetUserFeedback,
} from "@getuserfeedback/react-native";
import { Button, View } from "react-native";
const manifest = {
// Paste the sandbox manifest while manually testing on device.
initOptions: {
apiKey: "gx_sandbox_...",
defaultConsent: ["analytics.measurement", "analytics.storage"],
disableTelemetry: true,
enableDebug: true,
runtimeEndpoints: {
apiUrl: "http://192.168.1.10:3712/v1",
coreUrl: "http://192.168.1.10:3711/widget/core/v1/core.html",
},
},
loaderUrl: "http://192.168.1.10:3711/widget/loader/v1/gx_sandbox_.../loader.js",
commands: {
identify: {
userId: "sandbox-user-...",
traits: { email: "[email protected]" },
},
open: { flowId: "sur_..." },
track: {
name: "Checkout Started",
properties: { source: "react-native-sandbox" },
},
},
} satisfies {
commands: {
identify: { traits: Record<string, unknown>; userId: string };
open: { flowId: string };
track: { name: string; properties: Record<string, unknown> };
};
initOptions: GetUserFeedbackProviderProps["initOptions"];
loaderUrl: string;
};
function SandboxActions() {
const feedback = useGetUserFeedback();
return (
<View>
<Button
title="Identify"
onPress={() => {
void feedback.identify(
manifest.commands.identify.userId,
manifest.commands.identify.traits,
);
}}
/>
<Button
title="Track"
onPress={() => {
void feedback.track(
manifest.commands.track.name,
manifest.commands.track.properties,
);
}}
/>
<Button
title="Open"
onPress={() => {
void feedback.open(manifest.commands.open.flowId);
}}
/>
</View>
);
}
export function App() {
return (
<GetUserFeedbackProvider
initOptions={manifest.initOptions}
loaderUrl={manifest.loaderUrl}
onCommandError={console.error}
>
<SandboxActions />
</GetUserFeedbackProvider>
);
}