Skip to content

Repository files navigation

@seggwat/react-native

Feedback SDK for React Native and Expo: a feedback form, helpful / star / NPS rating prompts, and a headless API client for SeggWat.

  • Pure TypeScript, zero native code, zero runtime dependencies.
  • Works in Expo Go, the Expo managed workflow, and bare React Native — on iOS, Android, and web.

Install

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

react and react-native are peer dependencies (already present in any RN/Expo app).

Quickstart

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

import { SeggWatProvider, FeedbackButton } from '@seggwat/react-native';

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

That's it — the floating button opens a feedback form and submits to your project. Get your project key from the SeggWat dashboard.

Components

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

FeedbackButton

Floating button that opens the feedback form. Positioned via options.buttonPosition; styled icon (default) or labeled.

<FeedbackButton />

Open the form programmatically

import { useSeggWat } from '@seggwat/react-native';

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

HelpfulPrompt

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

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

StarRatingPrompt

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

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

NpsPrompt

Inline 0–10 Net Promoter Score row.

<NpsPrompt screenName="/home" />

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

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 one (still opened via present() or <FeedbackButton>):

<FeedbackSheet screenName="/settings" />

Headless usage

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

import { SeggWatClient } from '@seggwat/react-native';

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 });
console.log(res.id, res.ratingType);

Options

Pass options to SeggWatProvider via the options prop:

<SeggWatProvider projectKey="..." options={{ buttonColor: '#111', buttonStyle: 'labeled' }}>
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.
appVersion string App version sent with each submission.
appIdentifier string Sent as X-SeggWat-BundleID; add it to the project's Allowed Bundle IDs so native builds can submit (see below).
language "en" | "de" | "sv" auto-detected UI language; falls back to English.
apiUrl string "https://seggwat.com" API base URL (point at localhost for dev).
showPoweredBy boolean true Show "Powered by SeggWat" in the form.
onSubmit (result: SubmitResult) => void Fires after every submission (success or failure).

onSubmit receives { ok: true } on success or { ok: false, error } on failure — a small addition over the iOS SDK, which only reports success.

Allowing your app to submit (native)

On iOS and Android there is no browser Origin header, so a project whose Allowed Origins are set to specific origins returns 403 to native submissions.

Fix: set appIdentifier (sent as the X-SeggWat-BundleID header) and add that same identifier to Allowed Bundle IDs in the project's dashboard settings, next to Allowed Origins.

<SeggWatProvider projectKey="..." options={{ appIdentifier: 'com.acme.app' }}>

Use your iOS bundle ID / Android applicationId — the value passed here must match what you list in the dashboard.

Alternatively, add "*" to Allowed Origins, but that allows every web origin too — not recommended.

Expo web / react-native-web builds send a normal browser Origin, so they follow the origin allowlist instead of the bundle-ID list.

User attribution

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

<SeggWatProvider projectKey="..." user={{ id: 'user-123', email: 'ada@example.com' }}>
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.

Error handling

Submissions throw a SeggWatError. Branch on error.code:

import { SeggWatError } from '@seggwat/react-native';

try {
  await client.submitFeedback({ message });
} catch (err) {
  if (err instanceof SeggWatError) {
    switch (err.code) {
      case 'rate_limited':
        alert(`Please wait ${err.secondsRemaining}s and try again.`);
        break;
      case 'validation_failed':
        alert(err.message);
        break;
      case 'network_error':
        alert('Check your connection and try again.');
        break;
      default:
        alert(err.message);
    }
  }
}

Codes: invalid_project_key, validation_failed, rate_limited, server_validation_failed, origin_not_allowed, project_not_found, screenshot_too_large, unsupported_media_type, network_error, server_error, invalid_rating_value, duplicate_rating.

Submissions are rate-limited to one every 10 seconds per client.

Screenshot capture + annotation

The feedback form can capture the screen and open a fullscreen annotation editor (pen, arrow, rectangle, text, blackout — matching the iOS SDK and web widgets). The SDK contains no native code, so this is powered by react-native-view-shot (bundled in Expo Go), which you install and pass in — apps that skip it keep a dependency-free SDK and simply don't get the screenshot section:

bunx expo install react-native-view-shot   # or: bun add react-native-view-shot
import * as ViewShot from 'react-native-view-shot';

<SeggWatProvider
  projectKey="your-project-key"
  options={{ screenshots: { viewShot: ViewShot, quality: 0.8 } }}
>

With this set, the form shows a Screenshot button: the sheet hides, the screen behind it is captured, and the annotation editor opens. The annotated image is flattened and attached to the submission.

Screenshot attachment (headless)

You can also capture a screenshot yourself and pass its file URI:

import { useRef } from 'react';
import { View } from 'react-native';
import { captureRef } from 'react-native-view-shot';

function ReportButton() {
  const viewRef = useRef<View>(null);
  const { submitFeedback } = useSeggWat();

  async function report() {
    const uri = await captureRef(viewRef, { format: 'jpg', quality: 0.8 });
    await submitFeedback({
      message: 'Something looks off on this screen',
      screenshot: { uri }, // name/type default to screenshot.jpg / image/jpeg
    });
  }

  return (
    <View ref={viewRef} collapsable={false}>
      {/* ...your screen... */}
    </View>
  );
}

screenshot accepts { uri, name?, type? }. react-native-view-shot is an optional peer dependency — install it only if you want screenshots.

Localization

Ships with English (en), German (de), and Swedish (sv). The language is auto-detected from the device locale and falls back to English. Override it:

<SeggWatProvider projectKey="..." options={{ language: 'de' }}>

Links

License

MIT

About

SeggWat feedback SDK for React Native and Expo — feedback form, rating prompts, and screenshot annotation. Pure TypeScript, Expo Go compatible.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages