Expo
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:
- Setting up the Expo Module
- 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.
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
- 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:
...
"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.
Run npx expo prebuild --clean first if you don't have an ./ios folder.
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:
...
"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:
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:
...
"plugins": [
...
[
"./plugins/withIntelliProveAndroidManifest",
{}
]
]2. Expo Integration
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:
// 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 page.
- Finally, we call the handleOpenWebView()function from wherever the entry point to the WebView should be.
- 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 API endpoint.
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} />
...
)
}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 documentation.