React Native

React Native bridge over the same native chat SDKs, with the native chat screen presented from JS. RN 0.74+ (0.85+ recommended); runs on both the new TurboModule architecture and the old bridge. iOS 15.1+.

Install and quick startlink

npm install react-native-newinstance-chat
cd ios && pod install

Android needs mavenCentral() in settings.gradle.kts.

import { NewinstanceChat } from 'react-native-newinstance-chat';

const chat = new NewinstanceChat({ apiKey: 'sk_live_abc123' });
await chat.ready;
chat.setUser({ customerName: 'Ada', customerEmail: 'ada@example.com' });
await chat.initialize();
chat.openChat();

Config: { apiKey, baseUrl?, transport?: 'sse' | 'ws', initialMessage?, theme? }; user: { customerName required, customerEmail?, customerId?, customerToken? }. ready resolves once native configuration completes. initialize() and attachFile() return promises; setUser, setUserToken, openChat, closeChat, sendMessage, retryMessage, removeAttachment, clearAttachments and destroy return void.

Authenticated customerslink

customerToken carries a chat identity token minted by your backend. When set it is the authoritative identity - the server derives name, email and customer id from its signed claims - so nothing else is needed:

chat.setUserToken(tokenFromYourBackend);

customerId without a token is recorded for agent context only and is not treated as identity. See Authentication and identity.

Local themelink

const chat = new NewinstanceChat({
  apiKey: 'sk_live_abc123',
  theme: { mode: 'dark', sentBubble: '#16A34A' },
});

Every ChatThemeOverride field is optional and merged token by token, ranked below the merchant's dashboard theme and above the built-in palette. Full rules in Theming.

Eventslink

addListener(event, handler) returns an unsubscribe function; call it on unmount. Events: messageReceived, messageSent, agentTypingChanged, connectionStateChanged (idle, connecting, connected, disconnected, offline), unreadCountChanged, error, attachmentUpdated, chatClosed. ChatMessage carries clientId, seq, sentAt and totalMessages.

The error eventlink

error is the channel for "why is my chat not working". Nothing on it reaches the chat interface, and it never carries the API key, the identity token, or customer data.

const off = chat.addListener('error', (e) => {
  if (e.code === 'INVALID_IDENTITY_TOKEN') return refreshChatToken();
  if (!e.recoverable) reportToYourMonitoring(e.code, e.message);
});

NewinstanceChatError carries code (NewinstanceChatErrorCode, the vocabulary shared with every other chat SDK), the broad type (network, validation, auth, system), a developer-facing message, an optional developerMessage, and recoverable. code is undefined only when talking to a native SDK older than the release that introduced coded errors, so existing 0.2.x handlers that read type keep working. The full code list is in Authentication and identity -> Diagnosing problems.

Programmatic attachmentslink

attachFile({ source, sourceType?, name, mimeType?, size?, metadata? }) accepts base64, data URIs, local file paths, content:// and file:// URIs (document and image picker outputs), and remote URLs when the native SDK enables them; sourceType: 'auto' (default) safely detects string inputs, and the legacy { uri, name, mimeType } form keeps working. The promise resolves with the attachment id as soon as the request is queued; validation and upload run in the background and stream through attachmentUpdated (status: queued, uploading, uploaded, failed, cancelled; progress: real 0..1 byte progress). Validation covers base64 decoding, URI readability, empty files, the 25 MB cap, the png/jpeg/webp/gif/pdf MIME allowlist, size mismatches and extension/MIME disagreement. removeAttachment(id) cancels an in-flight upload; a message is never sent with an attachment that has not finished uploading.

The chat close eventlink

chatClosed fires exactly once per chat presentation: the in-chat X (close_button), Android back navigation (back_navigation), an iOS dismissal gesture (gesture), closeChat() (programmatic), destroy() (session_ended), or the host navigating the screen away (host_navigation). Payload: reason, initiator (user/host/sdk), timestamp, conversationId, assignmentId, channel, previousState, unreadCount, hasDraft, pendingAttachmentCount, metadata. It never contains message contents, credentials or attachment data.

Gotchaslink

  • Handoff and typing indicators are driven by the native screen; there is no host API for them.
  • Multiple instances reconfigure the same native instance; the last configure wins. After destroy(), construct a new instance.
  • Same auth rule as every chat client: the publishable widget key ID only, never keyId:secret.
  • iOS build fails with 'NewinstanceChat-Swift.h' file not found: you are on 0.1.0, which only resolved the generated Swift header in static-library Podfiles. Upgrade to 0.1.1 or later (npm install react-native-newinstance-chat@latest, then cd ios && pod install); it supports both default static-library builds and use_frameworks! with any linkage.
  • The multi-source attachFile, attachmentUpdated, chatClosed and a working unreadCountChanged require 0.2.0 of this package and of the underlying native SDKs; pod install after upgrading.
  • theme, customerToken, setUserToken and coded errors require 0.3.0 of this package and of the underlying native SDKs; pod install after upgrading.