@contegris/rn-intellicon-chat-sdk
v1.1.1
Published
Intellicon Chat SDK - Core (platform-agnostic, text messaging out of the box)
Readme
@contegris/rn-intellicon-chat-sdk (Core)
Platform-agnostic chat SDK with text messaging out of the box
Zero native dependencies. Perfect for lightweight integrations, internal tools, or custom UI implementations.
Table of Contents
- Overview
- When to Use Core Package
- Features
- Installation
- Quick Start
- Configuration
- Props Reference
- API Reference
- Theming
- Headless Mode
- Events
- Offline Support
- Performance
- Troubleshooting
- FAQ
- License
Overview
The Core package is a lightweight, platform-agnostic chat SDK that provides:
- Real-time text messaging
- Image display (no upload capability)
- Complete UI components
- State management
- Offline queue
- Theme system
- TypeScript support
Bundle Size: ~1.5 MB (includes all dependencies)
Architecture
Core Package
├── Components (UI)
│ ├── Chat.tsx (main component)
│ ├── MessageBubble.tsx
│ ├── ImageBubble.tsx (display + download with downloadFile prop)
│ ├── ZoomableImage.tsx (pinch-to-zoom viewer, exported)
│ ├── FeedbackBubble.tsx
│ └── Snackbar.tsx
├── Hooks (Business Logic)
│ ├── useChat (main hook)
│ ├── useUpload (upload queue)
│ └── useConnectionStatus
├── Services (Singletons)
│ ├── SocketService (WebSocket)
│ ├── ApiService (HTTP)
│ ├── UploadManager (upload queue)
│ └── OfflineQueue (AsyncStorage)
└── Theme System
├── ThemeContext
└── TypographyWhen to Use Core Package
✅ Use Core If:
- You only need text messaging (no media uploads)
- You want the smallest bundle size (~1.5 MB)
- You're building an internal tool or support chat
- You want to avoid native module complexity
- You want to build a custom UI (headless mode with
useChathook) - You need maximum platform compatibility
❌ Don't Use Core If:
- You need media attachments (images, videos, audio, documents)
- → Use
@contegris/rn-intellicon-chat-sdk-expo(Expo projects) - → Use
@contegris/rn-intellicon-chat-sdk-cli(React Native CLI projects)
- → Use
Features
✅ What's Included
- Real-time Messaging: Socket.IO v2.3.0 with automatic reconnection
- Offline Support: Messages queued in AsyncStorage and sent when online
- Optimistic UI: Instant visual feedback for sent messages
- Paginated History: Infinite scroll with 20 messages per page
- Delivery Status: Visual indicators (pending ⏱ / delivered ✓✓)
- Date Separators: Automatic grouping by day
- Feedback Widget: Post-conversation star ratings
- Connection Monitoring: Real-time connection status
- Theme System: 50+ customization tokens
- TypeScript: 100% type coverage
- Headless Mode:
useChathook for custom UIs - Performance Tracking: Built-in APM hooks via
onPerformanceReport - iOS Audio Playback: Reliable play-till-end detection with
AVAudioPlayerDelegatesupport
❌ What's NOT Included
- Image Uploads: Can display images from URLs, but cannot upload
- Video Attachments: Not supported
- Audio Messages: Not supported
- Document Attachments: Not supported
- Camera Access: Not supported
- Gallery Access: Not supported
- Emoji Keyboard: Not supported
Upgrade Path: Install Expo or CLI package for full media support.
Installation
Step 1: Install Package
# npm
npm install @contegris/rn-intellicon-chat-sdk
# yarn
yarn add @contegris/rn-intellicon-chat-sdk
# pnpm
pnpm add @contegris/rn-intellicon-chat-sdkStep 2: Verify Peer Dependencies
The core package requires:
{
"react": ">=18",
"react-native": ">=0.74"
}Dependencies (Auto-Installed)
{
"@react-native-async-storage/async-storage": "^1.23.1",
"axios": "^1.15.2",
"date-fns": "^3.6.0",
"jwt-decode": "^4.0.0",
"lucide-react-native": "^0.395.0",
"react-native-safe-area-context": ">=4.0.0",
"react-native-svg": ">=15.0.0",
"socket.io-client": "^2.3.0"
}Step 3: No Additional Setup Required
The core package works immediately after installation. No native modules to link, no permissions to configure.
Quick Start
Basic Usage
import React from 'react';
import { Chat } from '@contegris/rn-intellicon-chat-sdk';
export default function App() {
return (
<Chat
user={{
participantId: 'user-123',
name: 'John Doe',
}}
config={{
baseUrl: 'https://democc.contegris.com:443',
appId: 'your-app-id',
title: 'Customer Support',
}}
onFeedbackSubmit={() => {
// Called when user submits the post-conversation rating
// e.g. navigation.goBack()
}}
/>
);
}That's it! The chat UI is now fully functional with:
- Real-time messaging
- Offline support
- Message history
- Connection status indicators
- Error handling
With Custom Theme
import { Chat } from '@contegris/rn-intellicon-chat-sdk';
<Chat
user={{ participantId: 'user-123', name: 'John Doe' }}
config={{ baseUrl: 'https://example.com', appId: 'app-id' }}
theme={{
backgroundColor: '#F5F5F5',
appBar: {
bgColor: '#2563EB',
titleStyle: { color: '#FFFFFF', fontSize: 18, fontWeight: '600' },
},
bubbleStyle: {
visitor: { bgColor: '#2563EB', textStyle: { color: '#FFFFFF' } },
agent: { bgColor: '#FFFFFF', textStyle: { color: '#000000' } },
},
}}
/>With History Loading
<Chat
user={{ participantId: 'user-123', name: 'John Doe' }}
config={{
baseUrl: 'https://example.com',
appId: 'app-id',
history: {
show: true, // Load previous messages
view: 'inSingleView', // Display mode
},
}}
/>Configuration
User Configuration
interface User {
participantId: string; // REQUIRED: Unique user identifier
name: string; // REQUIRED: Display name
fcmToken?: string; // OPTIONAL: Push notification token
}| Property | Type | Required | Description | Example |
|----------|------|----------|-------------|---------|
| participantId | string | ✅ Yes | Unique identifier (must be consistent across sessions) | "user-67890" |
| name | string | ✅ Yes | Display name shown in chat | "Jane Smith" |
| fcmToken | string | ❌ No | Firebase Cloud Messaging token for push notifications | "fcm-token-abc..." |
Config Object
interface Config {
baseUrl: string; // REQUIRED: Server URL
appId: string; // REQUIRED: App identifier
title?: string; // OPTIONAL: AppBar title
history?: History; // OPTIONAL: History settings
}| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| baseUrl | string | ✅ Yes | N/A | Intellicon server URL (include protocol and port) |
| appId | string | ✅ Yes | N/A | Widget identifier from Intellicon dashboard |
| title | string | ❌ No | "Chat" | Title displayed in AppBar |
| history.show | boolean | ❌ No | false | Whether to load previous messages |
| history.view | 'inSingleView' \| 'listView' | ❌ No | 'inSingleView' | History display mode |
Custom Data
<Chat
{...props}
customData={{
customerType: 'premium',
language: 'en',
department: 'billing',
}}
/>customData is forwarded to the server and can be used for:
- Customer segmentation
- Analytics tracking
- Agent routing
- Context preservation
Props Reference
Chat Component
interface ChatProps {
user: User;
config: Config;
customData?: Record<string, unknown>;
theme?: ChatTheme;
downloadFile?: (params: { url: string; stopLoading: () => void; type: 'image' | 'video' | 'document'; fileName?: string }) => void;
onFeedbackSubmit?: () => void;
onPerformanceReport?: (report: PerformanceReport) => void;
showLogToggle?: boolean;
keyboardVerticalOffset?: number;
goBack?: () => void;
}| Prop | Type | Required | Description |
|------|------|----------|-------------|
| user | User | ✅ Yes | User identification object |
| config | Config | ✅ Yes | Server configuration |
| customData | Record<string, unknown> | ❌ No | Arbitrary metadata sent to server |
| theme | ChatTheme | ❌ No | Visual customization (50+ tokens) |
| downloadFile | function | ❌ No | Custom download handler for media (image, video, document) |
| onFeedbackSubmit | () => void | ❌ No | Called after user submits feedback. Use to navigate away or close the screen. |
| onPerformanceReport | function | ❌ No | Callback for APM integration |
| showLogToggle | boolean | ❌ No | Show debug toggle button (dev only) |
| keyboardVerticalOffset | number | ❌ No | Keyboard vertical offset for KeyboardAvoidingView on iOS |
| goBack | () => void | ❌ No | When provided, renders a back arrow in the AppBar. Use to navigate back (e.g., navigation.goBack()). |
API Reference
useChat Hook
The main hook for chat functionality. Returns stateful values and functions to control the chat.
import { useChat } from '@contegris/rn-intellicon-chat-sdk';
const {
messages,
isLoading,
isLoadingMore,
fatalError,
toastMsg,
dismissToast,
sendMessage,
sendMediaMessage,
cancelUpload,
retryUpload,
getTaskByUniqueId,
loadMore,
tokenData,
interactionId,
uploadTasks,
} = useChat(user, config, customData);Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| user | User | User identification |
| config | Config | Server configuration |
| customData | Record<string, unknown> (optional) | Arbitrary metadata |
Returns:
| Property | Type | Description |
|----------|------|-------------|
| messages | Message[] | Array of messages (newest first) |
| isLoading | boolean | Initial loading state |
| isLoadingMore | boolean | Pagination loading state |
| fatalError | string | Fatal error message |
| toastMsg | string | Toast message |
| dismissToast | () => void | Dismiss toast |
| sendMessage | (text: string) => void | Send text message |
| sendMediaMessage | (uri, name, mime, type, size) => Promise<void> | Send media (core doesn't upload) |
| cancelUpload | (uploadId, uniqueId) => void | Cancel upload |
| retryUpload | (uploadId) => void | Retry failed upload |
| getTaskByUniqueId | (uniqueId) => UploadTask \| undefined | Get upload task |
| loadMore | () => void | Load next page (20 messages) |
| tokenData | TokenData \| null | Server token data |
| interactionId | string | Current conversation ID |
| uploadTasks | ReadonlyMap<string, UploadTask> | All upload tasks |
Example: Custom UI with useChat
import React from 'react';
import { View, TextInput, Button, FlatList, Text } from 'react-native';
import { useChat } from '@contegris/rn-intellicon-chat-sdk';
export default function CustomChat() {
const { messages, isLoading, sendMessage, loadMore } = useChat(
{ participantId: 'user-123', name: 'John' },
{ baseUrl: 'https://chat.example.com', appId: 'app-id' }
);
const [text, setText] = React.useState('');
if (isLoading) return <Text>Loading...</Text>;
return (
<View style={{ flex: 1 }}>
<FlatList
data={messages}
keyExtractor={(item) => item.uniqueId || item.id}
renderItem={({ item }) => (
<Text>{item.author?.name}: {item.message}</Text>
)}
inverted
onEndReached={loadMore}
/>
<View style={{ flexDirection: 'row' }}>
<TextInput value={text} onChangeText={setText} />
<Button
title="Send"
onPress={() => {
sendMessage(text);
setText('');
}}
/>
</View>
</View>
);
}useConnectionStatus Hook
Monitor WebSocket connection status.
import { useConnectionStatus } from '@contegris/rn-intellicon-chat-sdk';
const status = useConnectionStatus();
// 'connected' | 'disconnected' | 'reconnecting' | 'reconnect_failed'Example:
const status = useConnectionStatus();
return (
<View>
{status === 'connected' && <Text style={{ color: 'green' }}>●</Text>}
{status === 'disconnected' && <Text style={{ color: 'red' }}>●</Text>}
{status === 'reconnecting' && <Text style={{ color: 'orange' }}>●</Text>}
</View>
);Services
SocketService
Singleton WebSocket manager.
import { SocketService } from '@contegris/rn-intellicon-chat-sdk';
// Check connection
const isConnected = SocketService.isConnected;
// Listen for connection changes
SocketService.onConnectionChange((status) => {
console.log('Connection status:', status);
});
// Disconnect (cleanup)
SocketService.disconnect();ApiService
HTTP client for token fetching and uploads.
import { ApiService } from '@contegris/rn-intellicon-chat-sdk';
ApiService.getToken(user, config, callback, eventCallback);OfflineQueue
Offline message queue (AsyncStorage-backed).
import OfflineQueue from '@contegris/rn-intellicon-chat-sdk';
OfflineQueue.load();
OfflineQueue.enqueue({ uniqueId, message, timestamp });
OfflineQueue.remove(uniqueId);
const pending = OfflineQueue.getAll();Theming
Customize every aspect of the UI using the ChatTheme interface. All properties are optional and fall back to DEFAULT_CHAT_THEME.
Theme Structure
The theme interface has 50+ properties organized into the following categories:
interface ChatTheme {
// Global
fontFamily?: string | null;
// Background
backgroundColor?: string;
backgroundImage?: string;
backgroundGradientColors?: string[];
backgroundGradientDirection?: 'horizontal' | 'vertical' | 'diagonal';
backgroundOverlay?: string;
// Loading & Error
loaderColor?: string;
loaderSize?: 'small' | 'large';
LoadingComponent?: React.ComponentType;
ErrorComponent?: React.ComponentType<{ message: string }>;
errorTextStyle?: TextStyle;
errorContainerStyle?: ViewStyle;
// Layout
containerStyle?: ViewStyle;
listContentStyle?: ViewStyle;
listPaddingVertical?: number;
listPaddingHorizontal?: number;
// Pagination
loadMoreThreshold?: number;
loadMoreLoaderColor?: string;
showLoadMoreSpinner?: boolean;
// Components
appBar?: AppBarStyle; // 7 properties
bubbleStyle?: BubbleStyle; // agent/visitor with audio/video/document styles
dateSeparator?: DateSeparatorStyle;
messageInput?: MessageInputStyle; // 14 properties
feedback?: FeedbackStyle; // 5 properties
}Quick Theme Examples
Minimal Dark Theme:
const theme: ChatTheme = {
fontFamily: 'Inter',
backgroundColor: '#0F172A',
appBar: { bgColor: '#1E293B', iconColor: '#60A5FA' },
};Light Theme:
const theme: ChatTheme = {
backgroundColor: '#FFFFFF',
appBar: {
bgColor: '#F5F5F5',
titleStyle: { color: '#000000' },
iconColor: '#2563EB',
},
bubbleStyle: {
visitor: { bgColor: '#2563EB', textStyle: { color: '#FFFFFF' } },
agent: { bgColor: '#E5E7EB', textStyle: { color: '#000000' } },
},
messageInput: { bgColor: '#F5F5F5', sendIconColor: '#2563EB' },
};Gradient Background:
const theme: ChatTheme = {
backgroundGradientColors: ['#667eea', '#764ba2', '#ee0979'],
backgroundGradientDirection: 'diagonal',
backgroundOverlay: 'rgba(0,0,0,0.3)',
};Custom Font:
const theme: ChatTheme = {
fontFamily: 'Inter', // Use custom font loaded by host app
// or
fontFamily: null, // Explicitly use system font (SF Pro / Roboto)
// omit fontFamily to use default 'Outfit' font
};Complete Theme Reference
For the full list of all 50+ theme properties with examples, see:
- Type Definition: theme.types.ts
- Default Values: DEFAULT_CHAT_THEME
- Detailed Guide: Root README Theming Section
Key Theme Objects
AppBarStyle (7 properties):
enabled,bgColor,gradientColors,gradientDirection,titleStyle,iconColor,centerTitle
BubbleStyle (agent/visitor with nested objects):
- Each bubble has:
bgColor,textStyle,audioMessage,videoMessage,documentMessage - Each media type has 3-5 style properties
MessageInputStyle (14 properties):
bgColor,inputContainerStyle,hintStyle,messageTextStyle,emojiIconColor,attachmentIconColor,attachmentModalBgColor,micInactiveIconColor,micActiveIconColor,micSendBgColor,sendIconColor,sendVoiceMessageIconColor,deleteVoiceMessageIconColor
FeedbackStyle (5 properties):
containerStyle,activeColor,inactiveColor,textActiveColor,textInactiveColor
DateSeparatorStyle (2 properties):
containerStyle,textStyle
Headless Mode
Use the useChat hook to build completely custom UIs without using the built-in components.
Example: Minimal Chat
import React from 'react';
import { View, TextInput, Button, FlatList, Text } from 'react-native';
import { useChat } from '@contegris/rn-intellicon-chat-sdk';
export default function MinimalChat() {
const { messages, sendMessage } = useChat(
{ participantId: 'user-123', name: 'John' },
{ baseUrl: 'https://example.com', appId: 'app-id' }
);
const [text, setText] = React.useState('');
return (
<View style={{ flex: 1 }}>
<FlatList
data={messages}
renderItem={({ item }) => <Text>{item.message}</Text>}
inverted
/>
<TextInput value={text} onChangeText={setText} />
<Button title="Send" onPress={() => sendMessage(text)} />
</View>
);
}Example: With Connection Status
import { useChat, useConnectionStatus } from '@contegris/rn-intellicon-chat-sdk';
const { messages, sendMessage } = useChat(user, config);
const status = useConnectionStatus();
return (
<View>
<Text>Status: {status}</Text>
{/* Your custom UI */}
</View>
);Events
Socket Events
The SDK uses Socket.IO for real-time communication.
Outgoing Events (Client → Server):
| Event | Payload | Description |
|-------|---------|-------------|
| new-message | { interactionId, message, author, uniqueId } | Send text message |
| open-interaction | {} | Request open interactions |
| new-interaction | { message, author, appId } | Create new conversation |
| interaction-message | { interactionId, offset } | Fetch messages (pagination) |
Incoming Events (Server → Client):
| Event | Payload | Description |
|-------|---------|-------------|
| ready | {} | Connection established |
| open-interactions | { interactions: [] } | List of open interactions |
| new-interaction | { interaction } | New interaction created |
| interaction-messages | { messages, count } | Batch of messages |
| new-message | { message } | New message received |
Event Listeners
import { SocketService } from '@contegris/rn-intellicon-chat-sdk';
// Listen for custom events
SocketService.onConnectionChange((status) => {
console.log('Connection:', status);
});
// Cleanup
SocketService.removeConnectionChangeListener(listener);Offline Support
How It Works
- Message Queued: When offline, messages are saved to AsyncStorage
- UI Updates: Optimistic UI shows message immediately (pending status)
- Auto-Sync: When connection restored, queued messages are sent automatically
- User Feedback: Toasts inform user ("Queued. Will send when online")
Storage Key
@intellicon:offline-queueData Structure
[
{
"uniqueId": "msg-123",
"message": "Hello",
"timestamp": 1642723200000,
"messageType": "text"
}
]Manual Control
import OfflineQueue from '@contegris/rn-intellicon-chat-sdk';
// Load queue from storage
await OfflineQueue.load();
// Get pending messages
const pending = OfflineQueue.getAll();
// Remove from queue
OfflineQueue.remove(uniqueId);Performance
Bundle Size
| Component | Size | |-----------|------| | Core Package | ~250 KB (uncompressed) | | Dependencies | ~1.2 MB (socket.io-client, axios, etc.) | | Total | ~1.5 MB |
Memory Usage
- Base: ~15 MB (React Native runtime included)
- Per Message: ~2-5 KB
- Recommended Max Messages in Memory: 500
Optimization Tips
Use React.memo for Custom Message Components:
const MessageItem = React.memo(({ message }) => { return <Text>{message.message}</Text>; });Use FlatList Optimizations:
<FlatList removeClippedSubviews={true} maxToRenderPerBatch={10} windowSize={21} />Memoize Theme:
const theme = useMemo(() => ({ ... }), []);
Troubleshooting
Common Issues
"Cannot resolve module @contegris/rn-intellicon-chat-sdk"
Solution:
npx react-native start --reset-cache"Failed to connect to server"
Cause: Invalid baseUrl or server unreachable.
Solution:
- Check baseUrl format:
https://example.com:443 - Test URL in browser
- Verify server is running
Messages Not Sending
Check:
- Internet connection
- Server URL correct
- AppId matches server configuration
- Check offline queue (messages queued if offline)
Debug Logging
Enable:
import { logger } from '@contegris/rn-intellicon-chat-sdk';
logger.setEnabled(true);Or use visual toggle:
<Chat {...props} showLogToggle={__DEV__} />Performance Monitoring
<Chat
{...props}
onPerformanceReport={(report) => {
console.log('Metric:', report.metric, 'Duration:', report.value, 'ms');
}}
/>FAQ
Can I use this without the UI components?
Yes! Use the useChat hook to build your own UI (headless mode).
Does this work with Expo?
Yes! The core package is platform-agnostic and works with both Expo and React Native CLI. For full media support, use the Expo package.
Can I display images?
Yes, images from URLs are displayed. However, uploading images is not supported (use Expo/CLI package).
How do I customize the theme?
Pass a theme prop with your custom styles. See Theming section.
Is TypeScript supported?
Yes! The package is written in TypeScript and includes complete type definitions.
How do I handle errors?
The SDK shows user-friendly error messages via toasts. Fatal errors show an error screen with retry button.
Can I use this in production?
Yes! The package is production-ready and battle-tested.
License
MIT License
Copyright (c) 2025 Contegris
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Support:
- Documentation: Root README
- Issues: GitHub Issues
- Email: [email protected]
Related Packages:
- @contegris/rn-intellicon-chat-sdk-expo - Full media support for Expo
- @contegris/rn-intellicon-chat-sdk-cli - Full media support for React Native CLI
