Embedding Livble in Your Mobile App
💡Overview
As a tenant portal provider, you might have a mobile app for your renters. If that is the case please make sure to read the following instructions to ensure the Livble experience and widget work properly.
NPM Package Version Requirements
- If you are using the new Livble SDK version, please make sure to use
>= 3.92.0- If you are using the old Livble SDK version (with
LivbleProvider), please make sure to use>= 2.0.71
ReactNative
The Livble SDK, Widget and Experience will work exactly as React web.
WebView based
If you are using a WebView to show a web app within your mobile app, Livble will work as usual. However, you will have to add the following configuration to the WebView props
import React, { useState, useCallback } from "react";
import { Linking } from "react-native";
import { WebView } from "react-native-webview";
const BASE_URL = "YOUR_URL";
export default function Index() {
const [
shouldOpenOAuthInExternalBrowser,
setShouldOpenOAuthInExternalBrowser,
] = useState(false);
/**
* Handle WebView navigation requests.
* Opens OAuth redirects in the external browser when the experience is open.
*/
const handleShouldStartLoadWithRequest = useCallback(
(event: { url: any }) => {
const { url } = event;
const isRedirect = url.includes("redirect_uri=");
if (isRedirect && shouldOpenOAuthInExternalBrowser) {
Linking.canOpenURL(url)
.then((supported) => {
if (supported) {
Linking.openURL(url).catch((err) =>
console.error("Failed to open URL:", err)
);
}
})
.catch((err) => console.error("Error checking URL support:", err));
return false; // Prevent WebView from handling the redirect
}
return true; // Allow WebView to handle other URLs
},
[shouldOpenOAuthInExternalBrowser]
);
/**
* Handles messages received from the WebView.
* Toggles whether OAuth links should open in an external browser.
*/
const handleWebViewMessage = (event: { nativeEvent: { data: any } }) => {
const { data } = event.nativeEvent;
// Ensure message is a valid JSON string before parsing
if (!data || typeof data !== "string") return;
try {
const parsedData = JSON.parse(data);
if (parsedData.eventType === "CLOSE_EXPERIENCE_REQUEST") {
setShouldOpenOAuthInExternalBrowser(false);
} else if (parsedData.eventType === "OPEN_EXPERIENCE_REQUEST") {
setShouldOpenOAuthInExternalBrowser(true);
}
} catch {}
};
/**
* Inject JavaScript to ensure window.postMessage is properly handled.
*/
const injectedJavaScript = `
(function () {
window.addEventListener(
"message",
function (event) {
window.ReactNativeWebView.postMessage(
typeof event.data === "string"
? event.data
: JSON.stringify(event.data)
);
},
false
);
})();
true; // Required for iOS
`;
return (
<WebView
source={{ uri: BASE_URL }}
onMessage={handleWebViewMessage}
injectedJavaScript={injectedJavaScript}
onShouldStartLoadWithRequest={handleShouldStartLoadWithRequest}
/>
);
}Flutter
Not supported natively yet
Android (Native)
Not supported natively yet
IOS (Native)
Not supported natively yet
Updated 4 months ago