Installation
react^18 or ^19socket.io-client^3 or ^4
Key Concepts
The ChatManager Hook
The ChatManager Hook
The package provides a hook called
useChatManager.
It internally manages the WebSocket connection and all state management required to create a seamless chat experience.For example, when a message is sent by the user, it is optimistically added to the message list before the server receives it. The hook automatically marks messages as accepted when the server acknowledges them, or marks them as failed if processing fails.Users and Threads
Users and Threads
The hook uses two key identifiers:
userId: A unique identifier for the end user. This should be consistent across sessions for the same user.threadId: A unique identifier for a conversation thread. Use the samethreadIdto continue an existing conversation, or generate a new one to start a fresh conversation.
Assistant ID
Assistant ID
The
assistantId specifies which assistant configuration to use. Different assistant IDs may have different prompts, behaviors, or capabilities configured on the server.Currently you shoudl use demo-text-voiceLoading History and Connecting
Loading History and Connecting
The hook provides two separate methods for initialization:
loadHistory(): Fetches previous messages for the thread via REST API. Call this to restore conversation history.connect(): Establishes the WebSocket connection for real-time messaging.
You can call loadHistory() and connect() in parallel. The hook handles the state correctly regardless of which completes first.
However, the user experience will be better if you let loadHistory() complete before allowing user to new send message. You can check if loadHistory is complete by checking
chat.isLoadingHistory.Automatic Cleanup: The hook automatically disconnects the WebSocket connection when the component unmounts. You do not need to call
disconnect() in a cleanup effect—it’s handled internally.Messages, Content Types, and States
Messages, Content Types, and States
Message Ordering
Themessages array is sorted in reverse chronological order (newest first). The most recent message is at index 0. This ordering is optimized for use with React Native’s FlatList with the inverted prop, which is the standard pattern for chat UIs.Message Structure
Each message in themessages array has the following structure:Content Types
Messages support three content types:- Text
- Image
- Audio
Optimistic Updates
When you send a message, it’s immediately added tomessages with optimistic: true. This provides instant feedback to the user.optimistic | failed | Meaning |
|---|---|---|
true | false | Message sent, awaiting server acknowledgment |
false | false | Server received the message |
true or false | true | Server failed to process the message |
Sending Media Messages
Sending Media Messages
For efficiecy and reliability, media messages are sent in two parts.First, we upload the media (image or audio) to the server and get back a mediaId string. Then we send a websocket message to the server containing just the mediaId.The hook automatically handles this for you, but it is still important that you understand this.Here is what happens when u call
sendImageMessage() or sendAudioMessage().- Optimistic Display: The message immediately appears in the message list using the local file URI
- Background Upload: The file is uploaded via REST API to
/api/media - WebSocket Message: Once uploaded, the message is sent via WebSocket with the server media ID
Displaying Media
Displaying Media
Media messages (images and audio) need their URLs constructed before display. The How
The helper constructs different URLs based on the
getMediaUrl() helper handles this for you.Images
For image messages, pass'media' as the source type:Audio
Audio messages include asource field that tells you how to construct the URL:How getMediaUrl Works
The helper constructs different URLs based on the source parameter:| Source | What It Returns | When It’s Used |
|---|---|---|
'media' | {apiBaseUrl}/api/media/{mediaId} | User-uploaded images and audio |
'mediastream' | {apiBaseUrl}/api/mediastream/get?... | AI-generated audio responses |
'url' | Returns mediaId as-is | When the ID is already a complete URL |
Sending Messages
- Text
- Image
- Audio
Types
- ChatManager
- ChatManagerOptions
- Messages
Complete Example
This example shows a minimal chat screen with text and voice messages, connection status, and optimistic updates.
This example is simplified for clarity. In a production app you would:
- Get
authTokenanduserIdfrom your authentication system - Generate a new
threadId(e.g.,crypto.randomUUID()) when starting a new conversation, or pass an existing one to continue a conversation - Add image message rendering and a more polished audio player with progress/duration
