> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vouchmark.com/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native

> Embed the Vouchmark KYB widget in your React Native app.

`@vouchmark/widget-react-native` wraps the Vouchmark widget in a native WebView, with camera and microphone access enabled for document scans and liveness checks. It ships both a full-screen `VouchmarkWidget` and a `VouchmarkModal`.

## Installation

```bash theme={null}
npm install @vouchmark/widget-react-native
# or
pnpm add @vouchmark/widget-react-native
# or
yarn add @vouchmark/widget-react-native
```

### Peer dependencies

The package requires `react-native-webview`:

```bash theme={null}
npm install react-native-webview
```

For iOS, run `cd ios && pod install` after installation.

## Quick start

```tsx theme={null}
import { VouchmarkWidget } from "@vouchmark/widget-react-native";

export function KybScreen() {
  return (
    <VouchmarkWidget
      widgetId="wgt_your_widget_id"
      publicKey="live_pk_your_public_key"
      environment="live"
      applicant={{
        email: "applicant@example.com",
        businessName: "Acme Ltd",
      }}
      onSuccess={(applicant) => {
        navigation.navigate("Dashboard", { applicantId: applicant.id });
      }}
      onAbandon={() => {
        navigation.goBack();
      }}
      onError={(error) => {
        Alert.alert("Verification error", error.message);
      }}
    />
  );
}
```

## Props

| Prop                | Type                                   | Required | Description                                                                                                            |
| ------------------- | -------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `widgetId`          | `string`                               | Yes      | Widget ID from the dashboard. Must match the widget's `environment` (see [Environments](/sdks/overview#environments)). |
| `publicKey`         | `string`                               | Yes      | Publishable key: `test_pk_…` for sandbox, `live_pk_…` for live.                                                        |
| `environment`       | `"sandbox" \| "live"`                  | Yes      | Must match the key prefix and widget: `"sandbox"` with `test_pk_…`, `"live"` with `live_pk_…`.                         |
| `applicant`         | `ApplicantInput`                       | No       | Pre-fill applicant fields.                                                                                             |
| `referenceId`       | `string`                               | No       | Your internal reference ID.                                                                                            |
| `sessionToken`      | `string`                               | No       | Signed server token for secure mode.                                                                                   |
| `locale`            | `string`                               | No       | Language. Default `"en"`.                                                                                              |
| `presentationStyle` | `"fullScreen" \| "modal"`              | No       | Presentation hint passed to the widget.                                                                                |
| `onSuccess`         | `(applicant: ApplicantResult) => void` | No       | Fires on approval.                                                                                                     |
| `onAbandon`         | `() => void`                           | No       | Fires when user closes early.                                                                                          |
| `onError`           | `(error: WidgetError) => void`         | No       | Fires on unrecoverable error.                                                                                          |
| `onStepCompleted`   | `(step: StepResult) => void`           | No       | Fires after each module.                                                                                               |

## Modal presentation

To show the widget as a modal instead of full-screen:

```tsx theme={null}
import { useState } from "react";
import { VouchmarkModal } from "@vouchmark/widget-react-native";

export function KybButton() {
  const [visible, setVisible] = useState(false);

  return (
    <>
      <Button title="Start KYB" onPress={() => setVisible(true)} />
      <VouchmarkModal
        visible={visible}
        widgetId="wgt_..."
        publicKey="live_pk_..."
        environment="live"
        onSuccess={(applicant) => {
          setVisible(false);
          // handle success
        }}
        onAbandon={() => setVisible(false)}
        onDismiss={() => setVisible(false)}
      />
    </>
  );
}
```

## Permissions

The widget may need camera access for liveness checks and document scans. Add to your app config:

### iOS (`Info.plist`)

```xml theme={null}
<key>NSCameraUsageDescription</key>
<string>Camera access is needed for identity verification</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is needed for document upload</string>
```

### Android (`AndroidManifest.xml`)

```xml theme={null}
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```

## Expo support

The package works with Expo (managed workflow) when `react-native-webview` is installed via `expo install`:

```bash theme={null}
npx expo install react-native-webview
npm install @vouchmark/widget-react-native
```

### Environment variables

Copy `.env.example` to `.env` and set:

| Variable                           | Example                        | Description                                                                         |
| ---------------------------------- | ------------------------------ | ----------------------------------------------------------------------------------- |
| `EXPO_PUBLIC_API_URL`              | `https://api.vouchmark.com/v1` | Vouchmark API base URL (include `/v1`). Same host for staging and production.       |
| `EXPO_PUBLIC_VOUCHMARK_WIDGET_ID`  | `kyb_…` or `wgt_…`             | Widget ID from the dashboard — same environment as your key.                        |
| `EXPO_PUBLIC_VOUCHMARK_PUBLIC_KEY` | `test_pk_…` or `live_pk_…`     | Publishable key from developer settings.                                            |
| `EXPO_PUBLIC_VOUCHMARK_ENV`        | `sandbox` or `live`            | Must match the key and widget: `sandbox` with `test_pk_…`, `live` with `live_pk_…`. |

```bash theme={null}
EXPO_PUBLIC_API_URL=https://api.vouchmark.com/v1
EXPO_PUBLIC_VOUCHMARK_WIDGET_ID=kyb_your_widget_id
EXPO_PUBLIC_VOUCHMARK_PUBLIC_KEY=test_pk_your_key
EXPO_PUBLIC_VOUCHMARK_ENV=sandbox
```

The WebView loads the widget from `https://widget.vouchmark.com` by default. That page bootstraps against `https://api.vouchmark.com/v1`. All three widget credentials must align — see [Environments](/sdks/overview#environments).

After changing `.env`, restart Metro with a clean cache: `npx expo start -c`.

## Platform support

| Platform | Minimum version |
| -------- | --------------- |
| iOS      | 13.0+           |
| Android  | API 21 (5.0)+   |
| Expo     | SDK 49+         |
