React Native Chatbot SDK — Release Notes
Version history for dialogs_chatbot_reactnative, the official React Native SDK for
integrating the EnableX Dialogs conversational AI chat bot into apps on iOS and Android.
Releases are shown in reverse chronological order — latest first.
This is the first published release of the React Native Chatbot SDK. Supports iOS 15+ via a native WKWebView bridge and Android API 24+ via react-native-webview.
Package: npmjs.com/package/dialogs_chatbot_reactnative
What's Included
Core SDK (packages/sdk/)
| Module | File | Description |
|---|---|---|
| Bridge | src/bridge.ts | Dual-path platform bridge (iOS native + Android WebView) |
| Controller | src/controller.ts | State management, message queue, typing indicators |
| Widget | src/components/ChatWidget.tsx | Drop-in chat UI component with platform detection |
| Types | src/types.ts | All public TypeScript types, interfaces, and enums |
| Permissions | src/mediaPermissions.ts | Android runtime camera / mic / location helpers |
| Media Cache | src/cachedMedia.ts | Local media caching utilities |
| Parser | src/parser.ts | Incoming message envelope parser |
| Hooks | src/hooks.ts | useControllerVersion — triggers re-render on controller state change |
iOS Native Layer (sdk/ios/)
| File | Language | Role |
|---|---|---|
EnxChatBridge.h | Objective-C Header | Protocol declarations (EnxChatEventEmitter, EnxChatWebViewManager) |
EnxChatBridge.m | Objective-C | RCTEventEmitter module; exposes NativeModules.EnxChatBridge to JS |
EnxChatBridge.swift | Swift 5 | WKWebView manager; loads chat page off-screen; routes events |
Platform Support
| Platform | Minimum Version | WebView | Native Module |
|---|---|---|---|
| iOS | 15.0 | WKWebView (hidden, 300×300, off-screen) | EnxChatBridge (ObjC + Swift) |
| Android | API 24 | react-native-webview v13+ (hidden 1×1 view) | None — pure React Native |
Peer Dependencies
| Package | Version | Purpose |
|---|---|---|
react | >= 18 | React runtime |
react-native | >= 0.76 | React Native runtime |
react-native-webview | ^13.16.1 | Android WebView bridge + video call WebView |
react-native-image-picker | ^8.2.1 | Camera and gallery file picker |
@react-native-documents/picker | ^12.0.1 | Document file picker |
react-native-video | ^6.19.1 | Inline video message playback |
react-native-svg | ^15.15.1 | SVG icons in the UI |
react-native-markdown-display | ^7.0.2 | Markdown message rendering |
lucide-react-native | ^0.562.0 | UI icons |
@react-native-community/datetimepicker | ^9.1.0 | Calendar message type |
Features
- Auto-reconnect with configurable reconnect status banner.
- Typing indicator — animated bubble shown during bot response delay.
- Rich message types: text, image, video, file, markdown, link card, choices (single / multi), action buttons, calendar, system-centered notices.
- Video call support — full-screen
WebViewmodal launched when the bot sends a video-room URL (audio_video_action: start); dismissed onaudio_video_action: stopor back press. - Audio / video call buttons — optional UI in the input bar; wired to host-app handlers via
onAudioCall/onVideoCallprops. - File upload — camera capture, gallery picker, document picker.
- Theming — full colour customisation via
EnxChatTheme; two built-in themes:defaultThemeandmobileClassicTheme. - External controller —
EnxChatControllercan be created outside the widget to keep session alive across navigation and accessed imperatively. - Message queue — messages sent before the chat is
Readyare buffered and flushed automatically once the connection is established.
Public API Exports
// Components
export { EnxChatWidget } from './components/ChatWidget';
export { EnxChatScreen } from './components/ChatScreen';
// Controller
export { EnxChatController } from './controller';
// Types
export {
EnxBotConfig,
EnxMessage,
EnxMessageSender,
EnxMessageType,
EnxSuggestionType,
EnxChoice,
EnxAction,
EnxMedia,
EnxLinkCard,
EnxConnectionStatus,
EnxChatTheme,
EnxMessageDisplayStyle,
defaultTheme,
mobileClassicTheme,
} from './types';
Known Limitations
| # | Limitation | Planned |
|---|---|---|
| 1 | iOS WKWebView JS engine is paused when app goes to background. In-flight events may be missed. | v1.1 |
| 2 | No offline / cache-first support — requires network on every session start. | v1.2 |
| 3 | Video call WebView does not support picture-in-picture. | Backlog |
| 4 | Markdown rendering does not support tables. | Backlog |
Permissions Required
iOS — Info.plist keys:
<key>NSCameraUsageDescription</key>
<string>Camera is used for video calls with the support agent.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone is used for audio and video calls with the support agent.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location may be used when the chat page requests it.</string>
Android — AndroidManifest.xml permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
Runtime permissions for camera, microphone, and location are requested automatically by the SDK — no additional code needed in the host app.
Bug Fixes in This Release
Android — Console.log event forwarding broken after iOS native integration
Issue: After adding the iOS native WKWebView bridge, the androidBridge injected script was changed to wrap all console.log calls in a { type: 'CONSOLE', level: 'log', data: [...] } envelope. The onMessage handler in bridge.ts expected a { event, data } envelope, so all Android chat events (e.g. chatReady, connected, message) were silently discarded. The widget showed “Connecting…” indefinitely on Android.
Root cause: The chat page fires events via console.log(JSON.stringify({ event, data })). The androidBridge injection script was not forwarding these raw JSON strings directly.
Fix (ChatWidget.tsx — androidBridge constant):
// Before (broken — wraps every log in CONSOLE envelope)
console.log = function() {
var args = Array.prototype.slice.call(arguments);
sendToRN({ type: 'CONSOLE', level: 'log', data: args });
originalLog.apply(console, args);
};
// After (fixed — forwards raw string directly, matching iOS chatCallback behaviour)
console.log = function() {
var args = Array.prototype.slice.call(arguments);
if (args.length >= 1 && typeof args[0] === 'string') {
sendToRN(args[0]); // ← forwarded directly; onMessage parses as event
} else {
sendToRN({ type: 'CONSOLE', level: 'log', data: args });
}
originalLog.apply(console, args);
};
This aligns Android with the iOS behaviour where console.log is overridden to call window.webkit.messageHandlers.chatCallback.postMessage(message) directly with the raw string.
iOS Native Module — Design Notes
Why no bridging header?
The Swift file (EnxChatBridge.swift) deliberately imports no React headers. All React/RN types are confined to EnxChatBridge.m (ObjC). The two files communicate through ObjC protocols declared in EnxChatBridge.h.
Setting DEFINES_MODULE = YES in the podspec causes Xcode to auto-generate a <pod>-Swift.h umbrella header. EnxChatBridge.m then sees the Swift class name EnxChatBridgeImpl in the ObjC runtime via NSClassFromString(@"EnxChatBridgeImpl") — no import required. This design avoids the chicken-and-egg problem where *-Swift.h doesn't exist before the first successful build.
Why a retain-cycle proxy?
WKUserContentController strongly retains its script message handlers. Without a proxy, the retain cycle would be:
EnxChatBridgeImpl → WKWebView → WKUserContentController → handler → EnxChatBridgeImpl
EnxScriptProxy holds only a weak var target, breaking the cycle and allowing EnxChatBridgeImpl to be deallocated when the controller is disposed.
Why non-zero WKWebView frame?
A zero-sized WKWebView silently skips JavaScript execution on some iOS versions. The WebView is positioned off-screen at (-1200, -1200) with a 300×300 frame so the JS engine always initialises correctly. It is attached to the active key window to keep the engine running while the app is in the foreground.
Support
For integration questions or to report a bug, contact the EnableX development team or file an issue in the internal repository.