React Native / Expo

Add a feedback form and helpful / star / NPS rating prompts to your React Native or Expo app.

Overview

The @seggwat/react-native SDK adds a feedback form and inline rating prompts (helpful, star, NPS) to your React Native or Expo app. It talks to the same SeggWat API as the web widgets and iOS SDK.

  • Pure TypeScript, zero native code: works in Expo Go, the Expo managed workflow, and bare React Native — on iOS, Android, and web
  • Zero runtime dependencies: react and react-native are the only peers (already in any RN/Expo app)
  • Drop-in components: a floating feedback button, an auto-hosted feedback form, and helpful / star / NPS prompts
  • Headless client: SeggWatClient for custom UIs and background submissions

Installation

@seggwat/react-native is on npm (current version 0.2.0, the first release):

bash
bun add @seggwat/react-native
# or: npm install @seggwat/react-native

Quickstart

Wrap your app in SeggWatProvider with your project key and drop a FeedbackButton anywhere inside it:

tsx
export default function App() {
  return (
    <SeggWatProvider projectKey="your-project-key">
      <YourApp />
      <FeedbackButton />
    </SeggWatProvider>
  );
}

The floating button opens a feedback form and submits to your project. Get your project key from Project Settings in the SeggWat dashboard.

You can also open the form programmatically instead of using the floating button:

tsx
function HelpMenu() {
  const { present } = useSeggWat();
  return <Button title="Send feedback" onPress={present} />;
}

Components

All components read config and the API client from SeggWatProvider, so they must be rendered inside it.

FeedbackSheet

The provider renders the feedback form for you, so you normally never mount FeedbackSheet yourself. Mount it only to attach a screen/path to submissions from the built-in form — your instance then replaces the provider's default (still opened via present() or <FeedbackButton>):

tsx
<FeedbackSheet screenName="/settings" />

HelpfulPrompt

Inline "Was this helpful?" card with Yes / No.

tsx
<HelpfulPrompt screenName="/docs/getting-started" onSubmitted={(r) => console.log(r.id)} />

StarRatingPrompt

Inline star rating (1–maxStars, default 5).

tsx
<StarRatingPrompt maxStars={5} screenName="/checkout" />

NpsPrompt

Inline 0–10 Net Promoter Score row.

tsx
<NpsPrompt screenName="/home" />

Each prompt takes an optional screenName and an onSubmitted?: (r: RatingCreatedResponse) => void callback.

Screenshot capture & annotation

The feedback form can capture the screen and open a fullscreen annotation editor. The SDK ships no native code, so this is opt-in: install react-native-view-shot (bundled in Expo Go) and pass the module into options.screenshots. Apps that skip it keep a dependency-free SDK and simply don't get the screenshot section.

bash
npx expo install react-native-view-shot
tsx
<SeggWatProvider
  projectKey="your-project-key"
  options={{ screenshots: { viewShot: ViewShot } }}
>

With this set, the form shows a Screenshot button. For the end user, the flow is:

  1. Tap Screenshot — the sheet hides and the screen behind it is captured
  2. The annotation editor opens with pen, arrow, rectangle, text, and blackout tools (matching the iOS SDK and web widgets)
  3. The annotated image is flattened and attached to the submission

Headless usage

Skip the components and talk to the API directly with SeggWatClient — useful for custom UIs or background submissions.

ts
const client = new SeggWatClient({
  projectKey: 'your-project-key',
  appVersion: '1.4.0',
  // apiUrl defaults to https://seggwat.com
});

// Feedback
await client.submitFeedback({ message: 'Love the new dashboard!', screenName: '/home' });

// Ratings (tagged union: helpful | star | nps)
await client.submitRating({ type: 'helpful', value: true }, { screenName: '/docs' });
await client.submitRating({ type: 'star', value: 4 }, { screenName: '/checkout' });
const res = await client.submitRating({ type: 'nps', value: 9 });

Submissions throw a SeggWatError with a code (for example rate_limited, validation_failed, network_error) you can branch on. Submissions are rate-limited to one every 10 seconds per client.

User attribution

Attribute submissions to a signed-in user. Set it once on the provider, or update it later via the hook:

tsx
<SeggWatProvider projectKey="..." user={{ id: 'user-123', email: 'ada@example.com' }}>
tsx
const { setUser } = useSeggWat();
setUser('user-123', 'ada@example.com'); // after login
setUser();                              // clear on logout

id is sent as submitted_by, email as submitted_by_email.

Theming & localization

Pass options to SeggWatProvider via the options prop:

tsx
<SeggWatProvider projectKey="..." options={{ buttonColor: '#111', theme: 'dark' }}>
Option Type Default Description
buttonColor string "#3b7299" Accent color of the floating button and prompts.
buttonPosition "bottomRight" | "bottomLeft" | "topRight" | "topLeft" "bottomRight" Floating button position.
buttonStyle "icon" | "labeled" "icon" Circular icon or a labeled pill.
theme "auto" | "light" | "dark" "auto" Color scheme; "auto" follows the device setting.
language "en" | "de" | "sv" auto-detected UI language; auto-detected from the device locale, falling back to English.
appVersion string App version sent with each submission.
showPoweredBy boolean true Show "Powered by SeggWat" in the form.

The SDK ships English (en), German (de), and Swedish (sv) and auto-detects the language from the device locale, so you only set language to override it.

Next Steps

Navigation