---
title: Expo
slug: technical-docs/expo
icon: 🧑‍💻
docTags: 
createdAt: 2024-11-20T13:45:26.860Z
---

# Introduction

Using the native iOS/Android WebView implies some extra setup in your Expo project. This setup involves incorporating the IntelliProve plug-in Mobile SDK as a pre-packaged Expo Module and adding the necessary bridging code.

All this is nicely laid out in our step-by-step guide below.

The integration guide covers  two sections:

1. Setting up the Expo Module
2. Interfacing with the Native code from Expo (*bridging*)

## GitHub

Our GitHub repository provides a fully functional example of our platform's integration, demonstrating the seamless setup and utilisation of our pre-packaged Expo Module.

[https://github.com/IntelliProve/intelliprove-web-plugin-expo](https://github.com/IntelliProve/intelliprove-web-plugin-expo)

## Minimal Requirements

For this guide, we assume a minimal 'Hello World' application generated by the Expo project initialisation.

# 1. Expo Module Setup

## Adding the framework

`Last update 22/08/2026 14:32`

::File{src="https://api.archbee.com/api/presign/_0R_DnpmBBLLXmaoWvG2u/ZtmYRI6-87tcURp9mmhqq_expo-intelliprovewebview-200.tgz" label="expo-intelliprovewebview-2.0.0.tgz"}

- Copy the `expo-intelliprovewebview-x.x.x.tgz` tarball into your Expo App root directory.
- In your Expo App root directory, execute `npm install /path/to/tarball/expo-intelliprovewebview-x.x.x.tgz`.

## Configuration for iOS

We need to configure the minimum deployment target of the application, and allow Camera Usage by the application.

- Open `app.json` and add:

```json
   ...
   
    "ios": {
      ...,
      "deploymentTarget": "15.0",
      "infoPlist": {
        "NSCameraUsageDescription": "We need camera permission for performing the measurement."
      }
    },

    ...
```

- Then run `npx pod-install` to ensure all iOS dependencies are added to your application.

:::hint{type="info"}
Run `npx expo prebuild --clean` first if you don't have an *./ios&#x20;*&#x66;older.
:::

## Configuration for Android

- Run `npx expo install expo-build-properties`. This allows you to edit the gradle build properties for the Android application.
- Then in `app.json` add the following, so we can set the correct SDK versions and permissions:

```json
    ...
    
    "android": {
      ...,
      "permissions": [
        "android.permission.INTERNET",
        "android.permission.CAMERA"
      ]
    },
    
    ...
    
    "plugins": [
      [
        "expo-build-properties",
        {
          "android": {
            "compileSdkVersion": 34,
            "targetSdkVersion": 34,
            "minSdkVersion": 24,
            "kotlinVersion": "1.8.0",
            "buildToolsVersion": "34.0.0"
          }
        }
      ],
      
      ...
    ]
```

We also need to do some updates to the Android Manifest, so we can run the IntelliProve module from the application.

- First, create a file at `plugins/withIntelliProveAndroidManifest.js` relative to the Expo Application root folder.
- In that file, add the following code:

```javascript
const { withAndroidManifest } = require("@expo/config-plugins");

function addUsesFeatureCameraToManifest(androidManifest) {
  const { manifest } = androidManifest;

  if (!Array.isArray(manifest["uses-feature"])) {
    manifest["uses-feature"] = [];
  }

  if (!manifest["uses-feature"].find(
    (item) => item.$["android:name"] === "android.hardware.camera"
  )) {
    manifest["uses-feature"]?.push({
      $: {
        "android:name": "android.hardware.camera",
        "android:required": "false",
      },
    });
  }

  return androidManifest;
}

function addIntelliWebViewActivityToManifest(androidManifest) {
  const { manifest } = androidManifest;

  if (!Array.isArray(manifest["application"])) {
    console.warn("withIntelliProveAndroidManifest: No application array in manifest?");
    return androidManifest;
  }

  const application = manifest["application"].find(
    (item) => item.$["android:name"] === ".MainApplication"
  );
  if (!application) {
    console.warn("withIntelliProveAndroidManifest: No .MainApplication?");
    return androidManifest;
  }

  if (!Array.isArray(application["activity"])) {
    application["activity"] = [];
  }

  if (!application["activity"].find(
    (item) => item.$["android:name"] === "com.intelliprove.webview.IntelliWebViewActivity"
  )) {
    application["activity"]?.push({
      $: {
        "android:name": "com.intelliprove.webview.IntelliWebViewActivity"
      },
    });
  }

  return androidManifest;
}

module.exports = function withIntelliProveAndroidManifest(config, attributes) {
  return withAndroidManifest(config, (config) => {
    config.modResults = addUsesFeatureCameraToManifest(config.modResults);
    config.modResults = addIntelliWebViewActivityToManifest(config.modResults);
    return config;
  });
};
```

- Finally, add the following to `app.json`:

```json
    ...
    "plugins": [
      ...
      [
        "./plugins/withIntelliProveAndroidManifest",
        {}
      ]
    ]
```

# 2. Expo Integration

:::hint{type="info"}
While many possibilities exist to bridge the gap between Native iOS/Android and Expo, this document serves as a guide to integrating the IntelliProveSDK into an Expo application project.
:::

To be able to call functions on, and receive callbacks from the IntelliProve Expo Module, we need to import it in the Expo application.

- Open `App.tsx` or wherever in the Expo app that the IntelliProve web view will be used. (For newer Expo projects, add the code to the `RootLayout` in the *\_layout.tsx* file instead.)
- Add the following imports:

```javascript
// For registering the event listener
import { useEffect } from 'react';
// The IntelliProve expo module
import * as ExpoIntelliProveWebView from 'expo-intelliprovewebview';
```

- Add a function `handleOpenWebView` that calls the IntelliProve Expo Module to present the Web View
- Also add a callback handler for receiving 'PostMessage' messages.
  - The post messages allow you to **track the progress** of the Face Scan and **obtain the results** from the IntelliProve plug-in immediately after the user has performed the Face Scan. This allows you to use the results in your mobile app, enabling you to link actions to the results or design a custom results screen.
  - You can find an overview of the different types of messages on the [Message events](docId\:KZ6XSnd6V4G8EfCgd02ib) page.
- Finally, we call the `handleOpenWebView()`function from wherever the entry point to the WebView should be.&#x20;
- The URL to open the IntelliProve Face Scan Plug-in (webapp) is also passed to this function. In our example, it is added on a Button press handler.
  - Make sure to request the  URL for the Face Scan plug-in using the [Get Face Scan URL](docId\:BiuPVixvHltbukKLR2ATI) API endpoint.

```typescript
export default function App() {
  const handleOpenWebView = () => {
    ExpoIntelliProveWebView.presentWebView('https://<subdomain.intelliprove.com/...');
  };

  // Add Event Listener for IntelliWebViewPostMessage API
  useEffect(() => {
    // Make sure the name of the listener matches what was used on Native code
    const subscription = ExpoIntelliProveWebView.addPostMessageListener((event) => {
      // Handle the received postMessage
      console.log('Expo PostMessage Full Body:', event.postMessage);

      try {
        // The PostMessage is received as a JSON String, so we need to parse it
        const parsedMessage = JSON.parse(event.postMessage);
        if (parsedMessage && parsedMessage.stage) {
          console.log('Expo PostMessage Stage:', parsedMessage.stage);
        } else {
          console.warn('Expo invalid PostMessage format:', parsedMessage);
        }
      } catch (error) {
        console.error('Expo error parsing PostMessage:', error);
      }
    });

    // Unsubscribe from the event when the component unmounts
    return () => {
      subscription.remove();
    };
  }, []);
  
  ...
  
  return (
    ...
    <Button title="Open WebView" onPress={handleOpenWebView} />
    ...
  )
}
```

:::hint{type="warning"}
The WebView is automatically dismissed by the SDK when receiving the `dismiss` post message.
:::

Now run the application as you normally would, for example:

- `npx expo prebuild --clean`
- `npx expo run:ios` or `npx expo run:android`

# Next steps

- To match the plug-in with your brand's colours and fonts, please visit our our [UI Customization](docId\:vzz-ODpLrSTmbHTHZKLLd) documentation.

