Copy your widget key
Dashboard → Widget Settings → Embed. Note your widget key (wk_…).
Add Wiretalk live chat to Android, iOS, React Native, and Flutter apps without a native SDK. Load the popout URL in a WebView with a JavaScript bridge for unread counts and visitor identity.
Your app loads the full chat UI in a WebView — messaging, attachments, voice notes, tickets, appointments, and voice/video calls all run inside the widget. Use the official SDK for faster setup, or copy the raw WebView snippets from Widget Settings → Embed.
| Platform | Path | Install |
|---|---|---|
| Android | android/wiretalk-android | Copy module into your app — see android/README.md |
| iOS | ios/WiretalkSDK | Swift Package Manager |
| React Native | react-native | npm install file:./wiretalk-sdk/react-native |
| Flutter | flutter | Copy lib/wiretalk_chat.dart or add as local package |
Get the SDK from GitHub ↗ or copy from your Wiretalk install sdk/ folder. Bridge event reference: BRIDGE.md. Publishing (Maven, npm): PUBLISHING.md. Demo apps: android/demo-app, ios/DemoApp, react-native/example, flutter/example.
Dashboard → Widget Settings → Embed. Note your widget key (wk_…).
Widget Settings → Allowed Domains → add app:com.example.app (your real bundle ID).
Use the URL below with platform and app_id query params. The dashboard Embed tab generates this for each platform.
Copy the platform SDK from sdk/, or paste the generated snippet from Widget Settings → Embed. Enable JavaScript and DOM storage.
Listen for unread:count and message:received to update tab badges or trigger local push notifications.
Test without building an app: open Preview mobile ↗ from Widget Settings (replace the widget key and bundle ID first).
Load this URL in your WebView. Replace YOUR_WIDGET_KEY and com.example.app with your values from Widget Settings.
https://www.wiretalk.tech/popout/YOUR_WIDGET_KEY?platform=android&app_id=com.example.app&locale=en&tab=chat
| Query param | Required | Description |
|---|---|---|
platform | Yes | android, ios, react-native, flutter, capacitor, or cordova |
app_id | Yes | Your app bundle ID (e.g. com.example.app) |
locale | No | Widget language — default en |
tab | No | Initial tab: chat or home |
visitor_uid | No | Resume an existing visitor session (UUID) |
visitor_name, visitor_email, visitor_phone | No | Pre-fill identity for logged-in app users |
app_version | No | Sent to visitor analytics |
Copy platform-specific WebView code from Dashboard → Widget Settings → Embed → Platform (Website, Android, iOS, React Native, Flutter).
| Setting | Android | iOS |
|---|---|---|
| JavaScript | javaScriptEnabled = true | Default on WKWebView |
| DOM storage | domStorageEnabled = true | Default enabled |
| Media (calls / voice notes) | mediaPlaybackRequiresUserGesture = false | allowsInlineMediaPlayback |
| Camera / mic permissions | Declare in AndroidManifest.xml | Add usage strings in Info.plist |
| Safe area (notch) | Popout mode applies env(safe-area-inset-*) padding automatically | |
Voice and video calls require HTTPS and a TURN server for reliable connectivity on mobile networks. See Voice & video on mobile WebView.
Mobile apps do not use a website hostname. Instead, add your bundle ID to Allowed Domains using the app: prefix:
app:com.example.app
Widget init sends platform and app_id instead of a page URL. Requests are rejected if the bundle ID is not on your allowlist. See the domain restrictions guide.
Enable JavaScript, DOM storage, and a WiretalkAndroid JavaScript interface to receive bridge events.
<!-- Wiretalk — Android (Kotlin WebView) -->
<!-- Add app:com.example.app to Allowed Domains -->
/*
class WiretalkChatActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val webView = WebView(this)
setContentView(webView)
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.mediaPlaybackRequiresUserGesture = false
webView.webChromeClient = WebChromeClient()
webView.addJavascriptInterface(object {
@JavascriptInterface
fun postMessage(payload: String) {
runOnUiThread { handleWiretalkEvent(payload) }
}
}, "WiretalkAndroid")
webView.loadUrl("https://www.wiretalk.tech/popout/YOUR_WIDGET_KEY?locale=en&tab=chat&platform=android&app_id=com.example.app")
}
}
*/
Use WKWebView with a script message handler named wiretalk.
<!-- Wiretalk — iOS (Swift WKWebView) -->
<!-- Add app:com.example.app to Allowed Domains -->
/*
import WebKit
final class WiretalkChatController: UIViewController, WKScriptMessageHandler {
private lazy var webView: WKWebView = {
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "wiretalk")
config.defaultWebpagePreferences.allowsContentJavaScript = true
return WKWebView(frame: .zero, configuration: config)
}()
override func viewDidLoad() {
super.viewDidLoad()
view = webView
webView.load(URLRequest(url: URL(string: "https://www.wiretalk.tech/popout/YOUR_WIDGET_KEY?locale=en&tab=chat&platform=ios&app_id=com.example.app")!))
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard message.name == "wiretalk" else { return }
// Handle unread:count, message:received, etc.
}
}
*/
// Wiretalk — React Native (react-native-webview)
// npm install react-native-webview
// Add app:com.example.app to Allowed Domains
import WebView from 'react-native-webview';
export function WiretalkChat({ onUnreadCount }) {
return (
<WebView
source={{ uri: 'https://www.wiretalk.tech/popout/YOUR_WIDGET_KEY?locale=en&tab=chat&platform=react-native&app_id=com.example.app' }}
javaScriptEnabled
domStorageEnabled
mediaPlaybackRequiresUserAction={false}
allowsInlineMediaPlayback
onMessage={(event) => {
const msg = JSON.parse(event.nativeEvent.data);
if (msg.type === 'unread:count') onUnreadCount?.(msg.count);
}}
/>
);
}
// Wiretalk — Flutter (webview_flutter)
// Add app:com.example.app to Allowed Domains
import 'package:webview_flutter/webview_flutter.dart';
class WiretalkChatPage extends StatefulWidget {
@override
State<WiretalkChatPage> createState() => _WiretalkChatPageState();
}
class _WiretalkChatPageState extends State<WiretalkChatPage> {
late final controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadRequest(Uri.parse('https://www.wiretalk.tech/popout/YOUR_WIDGET_KEY?locale=en&tab=chat&platform=flutter&app_id=com.example.app'));
@override
Widget build(BuildContext context) {
return WebViewWidget(controller: controller);
}
}
When loaded inside a native WebView, the widget posts JSON messages your app can listen for. Use these to update tab badges, show local notifications, or sync visitor identity.
| Event type | When | Payload |
|---|---|---|
widget:ready | After init completes | visitor_uid, conversation_id, platform, app_id |
unread:count | Unread agent messages change | count, conversation_id |
message:received | New agent message arrives | message_id, body, conversation_id |
widget:state | Panel opens or closes | open, tab, conversation_id |
{
"type": "unread:count",
"count": 3,
"conversation_id": 42,
"platform": "android"
}
Post messages from native code to open the chat, update visitor identity, or control the widget:
| Type | Effect |
|---|---|
widget:open | Open chat panel (optional tab: chat or home) |
widget:close | Close chat panel |
widget:toggle | Toggle open/closed |
visitor:update | Update visitor name, email, phone |
storage:set / storage:remove | Sync visitor_uid across app restarts |
{
"wiretalk": true,
"type": "visitor:update",
"visitor": {
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "9876543210"
}
}
Wrap outbound messages with "wiretalk": true when posting from native code into the WebView. On Android, use WiretalkAndroid.postMessage(JSON.stringify(payload)). On iOS, use webkit.messageHandlers.wiretalk.postMessage(payload). React Native uses WebView.onMessage.
Pass visitor details via URL params when opening the WebView, or send a visitor:update bridge message after login:
https://www.wiretalk.tech/popout/YOUR_WIDGET_KEY?platform=ios&app_id=com.example.app&visitor_name=Jane&visitor_email=jane@example.com
See also: Pre-fill visitor identity for website embeds.
Text chat, attachments, pre-chat forms, tickets, KB search, appointments, account login OTP, voice notes, voice/video calls (HTTPS + permissions required).
Push notifications (FCM/APNs), background reconnect, and secure storage of visitor_uid. Wiretalk provides bridge events; your app decides how to surface them.