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.

v1.0.0 — June 25, 2026
Initial Release

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/)

ModuleFileDescription
Bridgesrc/bridge.tsDual-path platform bridge (iOS native + Android WebView)
Controllersrc/controller.tsState management, message queue, typing indicators
Widgetsrc/components/ChatWidget.tsxDrop-in chat UI component with platform detection
Typessrc/types.tsAll public TypeScript types, interfaces, and enums
Permissionssrc/mediaPermissions.tsAndroid runtime camera / mic / location helpers
Media Cachesrc/cachedMedia.tsLocal media caching utilities
Parsersrc/parser.tsIncoming message envelope parser
Hookssrc/hooks.tsuseControllerVersion — triggers re-render on controller state change

iOS Native Layer (sdk/ios/)

FileLanguageRole
EnxChatBridge.hObjective-C HeaderProtocol declarations (EnxChatEventEmitter, EnxChatWebViewManager)
EnxChatBridge.mObjective-CRCTEventEmitter module; exposes NativeModules.EnxChatBridge to JS
EnxChatBridge.swiftSwift 5WKWebView manager; loads chat page off-screen; routes events

Platform Support

PlatformMinimum VersionWebViewNative Module
iOS15.0WKWebView (hidden, 300×300, off-screen)EnxChatBridge (ObjC + Swift)
AndroidAPI 24react-native-webview v13+ (hidden 1×1 view)None — pure React Native

Peer Dependencies

PackageVersionPurpose
react>= 18React runtime
react-native>= 0.76React Native runtime
react-native-webview^13.16.1Android WebView bridge + video call WebView
react-native-image-picker^8.2.1Camera and gallery file picker
@react-native-documents/picker^12.0.1Document file picker
react-native-video^6.19.1Inline video message playback
react-native-svg^15.15.1SVG icons in the UI
react-native-markdown-display^7.0.2Markdown message rendering
lucide-react-native^0.562.0UI icons
@react-native-community/datetimepicker^9.1.0Calendar message type

Features

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

#LimitationPlanned
1iOS WKWebView JS engine is paused when app goes to background. In-flight events may be missed.v1.1
2No offline / cache-first support — requires network on every session start.v1.2
3Video call WebView does not support picture-in-picture.Backlog
4Markdown 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.tsxandroidBridge 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.