SnagRelayDocs
Installation

React Native SDK

Add bug reporting to your iOS and Android app. Put the key in .env, wrap the app once, then shake or tap Report.

react-native-snagrelay brings the same report flow to React Native: open it with a shake or the Report button, describe the problem, and the report arrives in your inbox with device info, recent console errors, network requests, and the last 15 screens. Your agent reads it over MCP like any other report.

On the project's Install tab, choose React Native. Copy the .env line (it already has your API key), then wrap the app as below. Do not paste the key into source.

Requirements

React Native 0.76 or later. Rebuild the native app after installing the peer packages. Works in a bare app, an Expo custom dev client, and Expo Go.

Install

npm install react-native-snagrelay
npm install react-native-view-shot react-native-svg react-native-device-info react-native-shake @react-native-picker/picker react-native-safe-area-context @react-native-async-storage/async-storage
cd ios && pod install

npm 7+ installs those peers automatically. Yarn does not — run the second line.

Put the key in .env

Keep the project key out of git. Expo inlines any EXPO_PUBLIC_* variable at bundle time. Restart Metro after you change .env.

# .env  (or .env.local)
EXPO_PUBLIC_SNAG_RELAY_API_KEY=YOUR_API_KEY

The Install tab shows this line with your real key. Only add a base URL if you are not on https://app.snagrelay.com:

EXPO_PUBLIC_SNAG_RELAY_BASE_URL=https://app.snagrelay.com

Wrap your app

Pass the env value into the provider. Expo only inlines EXPO_PUBLIC_* in your source, not inside node_modules, so this line has to live in the app.

import { Platform } from 'react-native';
import { SnagRelayProvider } from 'react-native-snagrelay';

export default function App() {
  const app = <YourApp />;

  if (Platform.OS !== 'web') {
    return (
      <SnagRelayProvider apiKey={process.env.EXPO_PUBLIC_SNAG_RELAY_API_KEY}>
        {app}
      </SnagRelayProvider>
    );
  }

  return app;
}

On a native-only app you can drop the Platform check.

Why not put the key in the JSX?

A hardcoded apiKey="…" works, but it ends up in git and in every build. The env pattern is the same one Expo uses for every other secret-ish public key.

Bare React Native, no Expo

Use your own env helper (react-native-config, Babel inline, …) or paste the key:

<SnagRelayProvider apiKey="YOUR_API_KEY">
  <YourApp />
</SnagRelayProvider>

Expo config plugin

Writes the key into extra.snagrelay (read through expo-constants). Still prefer .env so the key is not in app.json.

{ "expo": { "plugins": [["react-native-snagrelay", { "apiKey": "YOUR_API_KEY" }]] } }

Open a report

Rebuild, then:

  • TestFlight / release: shake the device, or tap the Report button.
  • Local development: shake opens the React Native / Expo developer menu, not the widget. Pick Report a Snag, or tap the button. Set shakeToOpen={true} if you want shake to open the widget in __DEV__ as well (both will fire).

iOS Simulator: Device → Shake. The Android emulator has no shake gesture.

Expo Go

Screenshots, the form, and network capture work in Expo Go. Shake uses expo-sensors (npx expo install expo-sensors). Device info falls back to Platform and expo-constants.

Screen trail (the last 15 screens)

There is no session replay on React Native. The stand-in is a screen trail: the last 15 routes, with token-like params redacted. It is opt-in.

Expo Router, once in the root layout:

import { usePathname, useGlobalSearchParams } from 'expo-router';
import { useSnagRelayScreenTrail } from 'react-native-snagrelay';

useSnagRelayScreenTrail(usePathname(), useGlobalSearchParams());

React Navigation:

import { trackNavigationState } from 'react-native-snagrelay';

<NavigationContainer onStateChange={trackNavigationState}>

Configure it from the dashboard

How reporters open it and what they see is set under Widget in the dashboard, not in code:

  • Launch: the floating button and your own button. See Launch.
  • Capture and Form: the first screen, markup tools, report types, and form fields. See Capture and Form.

React Native has no element picker (there is no DOM). Reports use the screenshot, annotations, and the screen trail.

Props

PropTypeDefaultNotes
apiKeystringfrom .env / pluginPrefer process.env.EXPO_PUBLIC_SNAG_RELAY_API_KEY
baseUrlstringhttps://app.snagrelay.comOr EXPO_PUBLIC_SNAG_RELAY_BASE_URL
user{ email?, name?, id? }noneAttribute reports to the signed-in user
autoShowButtonbooleantrueSet false to use only your own button or a shake
buttonPosition'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'from the project
theme{ primaryColor?, textColor?, iconColor?, backgroundColor? }noneOverrides the dashboard colours
shakeToOpenbooleantrue in production, false in __DEV__Shake is the dev-menu gesture locally
shakeSensitivity'low' | 'medium' | 'high''medium'Expo Go accelerometer fallback only
hapticFeedbackbooleantrue

Open it from your own button

import { SnagRelay } from 'react-native-snagrelay';

<Button title="Report a problem" onPress={() => SnagRelay.open()} />

SnagRelay.close() and SnagRelay.setUser({ email }) are also available.

What a report contains

  • Device and build: device info, app version and build, React Native version, Hermes, New Architecture, and with expo-updates the updateId, channel, and runtimeVersion
  • Network, with bodies: the last 50 requests, with string / JSON / text bodies up to 64 KB. Secrets are redacted on the device. Skipped when the plan does not include network capture
  • Console and JS errors
  • Screen trail: the last 15 screens, when you call the hook above
  • Screenshot with markup: pen, arrow, highlight, comment, and redact (paid plans)

Not included: session replay, video, or an element picker.

Screen trail and body capture need SDK 0.2 or later

Request bodies, the screen trail, and build metadata ship in react-native-snagrelay 0.2. Check your installed version if they're missing.

On this page