# WebView Integration

This guide explains how to integrate the Footprint onboarding flow into your Expo applications using the in-app WebView integration. Unlike `onboarding.initialize`, which launches the flow in an in-app browser, the WebView integration renders Footprint inside a native sheet (a page sheet on iOS, a bottom sheet on Android) that you control, with your own back button, close button, and toolbar styling.

**Note:** Make sure you have `@onefootprint/footprint-expo` version 3.4.0 or higher installed for the WebView integration to work properly.

## Camera permissions

If your onboarding flow includes ID document verification, you need to declare camera permissions in your app's `app.json` (or `app.config.js`). The WebView runs inside your app, so the camera prompt is gated by your app's manifest and `Info.plist` rather than a system browser.

```json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "We use the camera to verify your identity documents."
      }
    },
    "android": {
      "permissions": ["android.permission.CAMERA"]
    }
  }
}
```

## Getting started

1. **Wrap your app with `FootprintWebViewProvider`:**
   * The provider mounts the native sheet that hosts the Footprint WebView. It must be an ancestor of any component that calls `useFootprintWebView()`.

```javascript
import { FootprintWebViewProvider } from "@onefootprint/footprint-expo";

export default function App() {
  return (
    <FootprintWebViewProvider>
      {/* The rest of your app */}
    </FootprintWebViewProvider>
  );
}
```

2. **Create an onboarding session token**:
   * Obtain onboarding session token, e.g., `obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH`. Read [this article](/articles/guide/definitive-integration-guide#the-end-to-end-integration-step-3-create-an-onboarding-session-token).

3. **Initialize the Footprint Flow with the `useFootprintWebView` hook**:
   * Trigger Footprint, for example, when a button is clicked. Then, pass the `onboardingSessionToken` and `onComplete` callback to the `initialize` method.

```javascript
import { useFootprintWebView } from "@onefootprint/footprint-expo";
import { View, Button } from "react-native";

const Screen = () => {
  const { initialize } = useFootprintWebView();

  const launch = () => {
    initialize({
      onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
      onComplete: (validationToken) => {
        console.log(validationToken);
      },
    });
  };

  return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <Button onPress={launch} title="Launch Footprint" />
    </View>
  );
};
```

4. **Handle Completion:**
   * Once the user completes the flow, you'll receive the validationToken through the `onComplete` callback. Post this token to your backend for further processing.

## Listening to events

Footprint provides some events based on actions performed by the user. To listen to events, just pass them to the `initialize` method.

```typescript
initialize({
  onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
  onComplete: (validationToken) => {
    console.log(validationToken);
  },
  onError: (error) => {
    console.log(error);
  },
  onCancel: () => {
    console.log("User canceled the flow");
  },
  onClose: () => {
    console.log("User closed the flow");
  },
});
```

`onCancel` is triggered when the user taps the close button in the toolbar, swipes the sheet down, or taps the backdrop (Android).

## Setting a custom appearance

You can customize the appearance of the onboarding flow by passing an `appearance` object to the `initialize` method.

```typescript
initialize({
  onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
  onComplete: (validationToken) => {
    console.log(validationToken);
  },
  appearance: {
    variables: {
      borderRadius: "8px",
      colorSuccess: "#10b981",
      colorError: "#F87171",
      buttonPrimaryBg: "#5550e9",
    },
  },
});
```

For more information, including a list of available variables, check out the [customization guide](/articles/integrate/customization).

## Styling the sheet and toolbar

In addition to the in-flow `appearance`, the WebView integration lets you style the native sheet and the toolbar that wraps it. The toolbar shows the Footprint domain, a close button, and (when relevant) a back button.

```typescript
initialize({
  onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
  onComplete: (validationToken) => {
    console.log(validationToken);
  },
  sheetStyle: {
    backgroundColor: "#ffffff",
  },
  toolbarStyle: {
    backgroundColor: "#ffffff",
    buttonColor: "#000000",
    textColor: "#000000",
    separatorColor: "#c8c8cc",
  },
  options: {
    hideFootprintUrl: false,
  },
});
```

## Available Props

| Variable                 | Description                                                                                                                                                                                            |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onboardingSessionToken` | The onboarding session token you created.                                                                                                                                                              |
| `onComplete`             | Triggered after the user completes the onboarding flow. You'll receive a `validationToken` that your backend can exchange with Footprint to see the fp\_id, the login method used, and the KYC status. |
| `onError`                | Optional. A function that is called when there was an unrecoverable error while initializing the onboarding flow. It takes in an error string argument with more details.                              |
| `onCancel`               | Triggered when the user abandons the flow. This can be triggered when the user taps the close button in the toolbar, swipes the sheet down, or taps the backdrop.                                      |
| `onClose`                | Triggered when the user closes the flow (either completed or canceled).                                                                                                                                |
| `appearance`             | Optional. A `FootprintAppearance` object that customizes the look of your integration.                                                                                                                 |
| `l10n`                   | Optional. Specifies the desired localization. More information [here](/articles/integrate/customization#localization-configuration).                                                                   |
| `redirectUri`            | Optional. The URI scheme of your app, used to redirect back to your app from any external steps inside the flow.                                                                                       |
| `sheetStyle`             | Optional. `{ backgroundColor }`. Controls the background color of the sheet that contains the WebView.                                                                                                 |
| `toolbarStyle`           | Optional. `{ backgroundColor, buttonColor, textColor, separatorColor }`. Controls the appearance of the toolbar at the top of the sheet.                                                               |
| `options`                | Optional. `{ hideFootprintUrl }`. When `true`, hides the Footprint domain from the toolbar.                                                                                                            |