Build the WebView
Load an OmniLab experience in a React Native, iOS, or Android WebView, with the settings that matter.
Add OmniLab as a screen in your app. This page is for your mobile developer; it assumes WebView requirements are already confirmed.
React Native
npm install react-native-webviewimport React from "react";
import { WebView } from "react-native-webview";
export default function OmniLabScreen({ language, memberId }) {
const url =
`https://experience.example.com/<campaign-public-link>` +
`?embedded=1&c=<touchpoint-id>` +
`&l=${encodeURIComponent(language)}` +
(memberId ? `&fci=${encodeURIComponent(memberId)}` : "");
return (
<WebView
source={{ uri: url }}
style={{ flex: 1 }}
javaScriptEnabled
domStorageEnabled
sharedCookiesEnabled
thirdPartyCookiesEnabled
allowsInlineMediaPlayback
mediaPlaybackRequiresUserAction={false}
onShouldStartLoadWithRequest={(request) => {
// Keep OmniLab in the WebView; send anything else to the system browser.
return request.url.startsWith("https://experience.example.com");
}}
/>
);
}flex: 1 matters more than it looks — a WebView without it collapses to zero height and renders nothing, which reads as a loading failure.
The onShouldStartLoadWithRequest guard keeps external links (a sponsor's site, terms and conditions) out of your app shell where they would have no way back.
Native iOS
Use WKWebView. Enable JavaScript, allow inline media playback, and implement the media-capture permission delegate so a camera prompt inside the experience reaches the native prompt — without it the request is silently denied and a scan game appears broken.
Add the usage descriptions your experience needs to Info.plist (NSCameraUsageDescription, NSLocationWhenInUseUsageDescription). A missing description terminates the app when the permission is first requested.
Native Android
Use the standard WebView with javaScriptEnabled and domStorageEnabled. Implement onPermissionRequest in your WebChromeClient and grant it after checking the app's own runtime permission — the browser prompt and the Android permission are two separate gates and both have to pass.
Set setMediaPlaybackRequiresUserGesture(false) if the experience autoplays anything.
Passing your signed-in member through
If your app knows who the participant is, add fci to the address rather than making them sign in again inside the WebView. See Experience URLs for an app.
Keep credentials out of the app bundle
If your app also needs server-to-server access to OmniLab, do that from your own backend. Anything shipped in an app bundle can be extracted from it.
Debug checklist
- Confirm the WebView loads the right address, with
embedded=1and the language you expect. - Log the address you build — a mis-encoded parameter is the most common cause of "it opens the wrong campaign".
- Test camera and location on a real device, not a simulator.
- Test the keyboard against every form field.
- Background the app mid-experience and return.