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.

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
1{
2  "expo": {
3    "ios": {
4      "infoPlist": {
5        "NSCameraUsageDescription": "We use the camera to verify your identity documents."
6      }
7    },
8    "android": {
9      "permissions": ["android.permission.CAMERA"]
10    }
11  }
12}

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
1import { FootprintWebViewProvider } from "@onefootprint/footprint-expo";
2
3export default function App() {
4  return (
5    <FootprintWebViewProvider>
6      {/* The rest of your app */}
7    </FootprintWebViewProvider>
8  );
9}
  1. Start the onboarding:

    • Start the onboarding and get an onboarding token, e.g., obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH, from POST /onboardings.
  2. 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
1import { useFootprintWebView } from "@onefootprint/footprint-expo";
2import { View, Button } from "react-native";
3
4const Screen = () => {
5  const { initialize } = useFootprintWebView();
6
7  const launch = () => {
8    initialize({
9      onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
10      onComplete: (validationToken) => {
11        console.log(validationToken);
12      },
13    });
14  };
15
16  return (
17    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
18      <Button onPress={launch} title="Launch Footprint" />
19    </View>
20  );
21};
  1. 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
1initialize({
2  onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
3  onComplete: (validationToken) => {
4    console.log(validationToken);
5  },
6  onError: (error) => {
7    console.log(error);
8  },
9  onCancel: () => {
10    console.log("User canceled the flow");
11  },
12  onClose: () => {
13    console.log("User closed the flow");
14  },
15});

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
1initialize({
2  onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
3  onComplete: (validationToken) => {
4    console.log(validationToken);
5  },
6  appearance: {
7    variables: {
8      borderRadius: "8px",
9      colorSuccess: "#10b981",
10      colorError: "#F87171",
11      buttonPrimaryBg: "#5550e9",
12    },
13  },
14});

For more information, including a list of available variables, check out the customization guide.

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
1initialize({
2  onboardingSessionToken: "obtok_UxM6Vbvk2Rcy1gzcSuXgk3sj3L9I0pAnNH",
3  onComplete: (validationToken) => {
4    console.log(validationToken);
5  },
6  sheetStyle: {
7    backgroundColor: "#ffffff",
8  },
9  toolbarStyle: {
10    backgroundColor: "#ffffff",
11    buttonColor: "#000000",
12    textColor: "#000000",
13    separatorColor: "#c8c8cc",
14  },
15  options: {
16    hideFootprintUrl: false,
17  },
18});

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.
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.