From e72769b1b9e9104f3afe3665593bced20dacd5d8 Mon Sep 17 00:00:00 2001 From: rajdubey Date: Fri, 16 Oct 2026 12:12:14 +0530 Subject: [PATCH 1/3] docs(offline): offline support for the JavaScript SDK, React UI Kit and Angular UI Kit Add an Offline Support page under each product's messaging/core features: - sdk/javascript/offline-support (Messaging group) - ui-kit/react/offline-support and ui-kit/angular/offline-support (Features > Chat, after Core) Add an Offline Support section to the React and Angular core-features pages, list the pages in the llms indexes, and add the /ui-kit/react/v7/offline-support alias redirect that every React v7 page has. Content is limited to what is common to the Android, iOS, Flutter, JavaScript and React Native offline SDK lines. Co-Authored-By: Claude Opus 5.5 --- docs.json | 9 +- sdk/javascript/llms-javascript-v4.mdx | 1 + sdk/javascript/offline-support.mdx | 528 ++++++++++++++++++++++++++ ui-kit/angular/core-features.mdx | 12 +- ui-kit/angular/llms-angular-v5.mdx | 1 + ui-kit/angular/offline-support.mdx | 110 ++++++ ui-kit/react/core-features.mdx | 12 +- ui-kit/react/llms-react-v7.mdx | 1 + ui-kit/react/offline-support.mdx | 95 +++++ 9 files changed, 766 insertions(+), 3 deletions(-) create mode 100644 sdk/javascript/offline-support.mdx create mode 100644 ui-kit/angular/offline-support.mdx create mode 100644 ui-kit/react/offline-support.mdx diff --git a/docs.json b/docs.json index 96952f214..3c478e277 100644 --- a/docs.json +++ b/docs.json @@ -457,6 +457,7 @@ "group": "Chat", "pages": [ "ui-kit/react/core-features", + "ui-kit/react/offline-support", "ui-kit/react/extensions", "ui-kit/react/ai-features" ] @@ -2583,6 +2584,7 @@ "group": "Chat", "pages": [ "ui-kit/angular/core-features", + "ui-kit/angular/offline-support", "ui-kit/angular/extensions", "ui-kit/angular/ai-features" ] @@ -3160,7 +3162,8 @@ "sdk/javascript/transient-messages", "sdk/javascript/delivery-read-receipts", "sdk/javascript/mentions", - "sdk/javascript/reactions" + "sdk/javascript/reactions", + "sdk/javascript/offline-support" ] }, "sdk/javascript/calling-overview", @@ -10291,6 +10294,10 @@ "source": "/ui-kit/react/v7/core-features", "destination": "/ui-kit/react/core-features" }, + { + "source": "/ui-kit/react/v7/offline-support", + "destination": "/ui-kit/react/offline-support" + }, { "source": "/ui-kit/react/v7/event-system", "destination": "/ui-kit/react/event-system" diff --git a/sdk/javascript/llms-javascript-v4.mdx b/sdk/javascript/llms-javascript-v4.mdx index 98f212703..57a5ca476 100644 --- a/sdk/javascript/llms-javascript-v4.mdx +++ b/sdk/javascript/llms-javascript-v4.mdx @@ -59,6 +59,7 @@ parameters, long-tail methods, group/user management, calling, or edge-case list - [Delivery & Read Receipts](/sdk/javascript/delivery-read-receipts) - [Mentions](/sdk/javascript/mentions) - [Reactions](/sdk/javascript/reactions) +- [Offline Support](/sdk/javascript/offline-support) ## Calling - [Calling — Overview](/sdk/javascript/calling-overview) diff --git a/sdk/javascript/offline-support.mdx b/sdk/javascript/offline-support.mdx new file mode 100644 index 000000000..055406074 --- /dev/null +++ b/sdk/javascript/offline-support.mdx @@ -0,0 +1,528 @@ +--- +title: "Offline Support" +sidebarTitle: "Offline Support" +description: "Cache conversations and messages on the device, show them instantly, and queue messages sent without a connection with the CometChat JavaScript SDK." +--- + + + +| Field | Value | +| --- | --- | +| Package | `@cometchat/chat-sdk-javascript` | +| Import | `import { CometChat } from "@cometchat/chat-sdk-javascript";` | +| Enable | `new CometChat.AppSettingsBuilder().setOfflineConfig({ enabled: true, ... })` before `CometChat.init()` — offline support is **off by default** | +| Key methods | `CometChat.isOfflineEnabled()` · `CometChat.getPendingMessages()` · `CometChat.addSyncListener(name, listener)` / `CometChat.removeSyncListener(name)` · `CometChat.getOfflineEncryptionStatus()` | +| Two-phase reads | Pass a listener to `fetchPrevious()` / `fetchNext()` — e.g. `new CometChat.MessageFetchListener({ onCachedMessages, onServerMessages, onError })`; `CometChat.getConversation(with, type, new CometChat.SingleConversationFetchListener({...}))` | +| Queued sends | Pass `new CometChat.MessageSentListener({ onMessagePending, onMessageSent, onError })` as the second argument of `sendMessage()` / `sendMediaMessage()` / `sendCustomMessage()` | +| Offline send result | `onMessagePending` → `onError` (`FAILED_TO_FETCH`) and the Promise rejects, while the message stays queued → `onMessageSent` after reconnect. A send **without** a listener is not queued | +| Storage | Browser IndexedDB, one store per app ID and user, deleted on logout | +| Constraints | Cached reads skip any request that uses a server-only filter such as `setSearchKeyword()`. Encryption is opt-in and covers the database only, not cached media | +| Related | [Send a Message](/sdk/javascript/send-message) · [Receive a Message](/sdk/javascript/receive-message) · [Retrieve Conversations](/sdk/javascript/retrieve-conversations) · [Connection Status](/sdk/javascript/connection-status) | + + + +Offline support keeps a local copy of the logged-in user's conversations and messages on the device. Your app can render that copy the moment a screen opens — with or without a network — and the SDK replaces it with fresh server data as soon as it arrives. Messages sent while the device is offline are saved in a queue (the outbox) and sent automatically when the connection returns. + +Offline support is **opt-in**. Until you enable it, the SDK behaves exactly as it does today: nothing is stored on the device and every read goes to the server. + +## How It Works + +- **One local store per user.** The SDK keeps a separate store for each app ID and user, in the browser's IndexedDB. Logging out, or logging in as a different user, deletes the previous user's store. +- **Cached, then server.** When you pass a listener to a read such as `fetchPrevious()`, the SDK first hands you what it has cached, then the server's result. Every server result is written back to the cache. +- **Queued sends.** A message sent with a `MessageSentListener` is stored in the outbox first. If the device is offline, it stays queued and is sent automatically once the connection is back. +- **Catch-up sync.** After a reconnect, the SDK sends queued messages, then refreshes the cached conversations and messages so changes made while you were offline (new, edited and deleted messages) reach the cache. +- **The server wins.** If the cached copy and the server copy of a message differ, the server copy is kept. + +## Enable Offline Support + +Pass an offline configuration to `setOfflineConfig()` on the `AppSettingsBuilder`, then initialize the SDK as usual. Set `enabled: true` explicitly. + + + + ```typescript + let appID: string = "APP_ID"; + let region: string = "APP_REGION"; + + let appSetting: CometChat.AppSettings = new CometChat.AppSettingsBuilder() + .subscribePresenceForAllUsers() + .setRegion(region) + .setOfflineConfig({ + enabled: true, + maxPendingMessages: 50, + mediaCaching: CometChat.MediaCachingMode.AUTO, + }) + .build(); + + CometChat.init(appID, appSetting).then( + (initialized: boolean) => { + console.log("Initialization completed successfully", initialized); + }, + (error: CometChat.CometChatException) => { + console.log("Initialization failed with error:", error); + } + ); + ``` + + + ```javascript + let appID = "APP_ID"; + let region = "APP_REGION"; + + let appSetting = new CometChat.AppSettingsBuilder() + .subscribePresenceForAllUsers() + .setRegion(region) + .setOfflineConfig({ + enabled: true, + maxPendingMessages: 50, + mediaCaching: CometChat.MediaCachingMode.AUTO, + }) + .build(); + + CometChat.init(appID, appSetting).then( + () => { + console.log("Initialization completed successfully"); + }, + (error) => { + console.log("Initialization failed with error:", error); + } + ); + ``` + + + +The offline store opens when a user logs in (or an existing session is restored) and closes on logout. + + + Access the offline enums through the `CometChat` namespace — for example + `CometChat.MediaCachingMode.AUTO` and + `CometChat.PendingMessageOverflowPolicy.REJECT_NEWEST`. + + +### Configuration Options + +Every option is optional. Anything you leave out uses its default. + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `enabled` | `boolean` | `false` | Turns offline support on. Nothing is stored on the device unless this is `true`. | +| `maxPendingMessages` | `number` | `50` | How many messages the outbox can hold. Accepted range is 1–100. | +| `pendingQueueOverflowPolicy` | `CometChat.PendingMessageOverflowPolicy` | `REJECT_NEWEST` | What happens when the outbox is full: `REJECT_NEWEST` rejects the new send, `DROP_OLDEST` removes the oldest queued message to make room. | +| `autoSendPendingOnReconnect` | `boolean` | `true` | Sends queued messages automatically after a reconnect. It does not affect the catch-up sync. | +| `mediaCaching` | `CometChat.MediaCachingMode` | `AUTO` | `AUTO` downloads attachments of fetched and received messages so they can be viewed offline. `OFF` caches the message and its attachment details but not the file itself. | +| `maxMediaCacheSize` | `number` (bytes) | `524288000` (500 MB) | Space cached media may use. The least recently used files are removed first. `0` means no limit. | +| `encryption` | `boolean` | `false` | Encrypts the cached data at rest. See [Encrypt the Cache](#encrypt-the-cache). | + +## Check Whether Offline Is Running + +`CometChat.isOfflineEnabled()` returns `true` only while offline support is actually running for the logged-in user: you enabled it, a user is logged in, and the local store is open. It returns `false` before login, after logout, and when CometChat has switched offline support off for your app. Read it each time you need it instead of storing the value. + + + + ```typescript + let offlineRunning: boolean = CometChat.isOfflineEnabled(); + ``` + + + ```javascript + let offlineRunning = CometChat.isOfflineEnabled(); + ``` + + + +CometChat can turn offline support off for an app from the server. When that happens, the SDK stops using the local store, deletes the cached data and `isOfflineEnabled()` returns `false`. Your app keeps working online. + +## Read From the Cache, Then the Server + +Pass a fetch listener to a request's `fetchPrevious()` or `fetchNext()` to receive results in two steps: + +1. `onCached*` — what is stored on the device, delivered immediately. It can be an empty list. +2. `onServer*` — the server's result, which also updates the cache. If the device is offline, or the request fails, `onError` is called instead. + +The call still returns a Promise that settles with the server result, so handle the outcome in one place. Without a listener, the request reads from the server only, exactly as before. + +### Messages + + + + ```typescript + let UID: string = "UID"; + let limit: number = 30; + + let messagesRequest: CometChat.MessagesRequest = + new CometChat.MessagesRequestBuilder() + .setUID(UID) + .setLimit(limit) + .build(); + + messagesRequest + .fetchPrevious( + new CometChat.MessageFetchListener({ + onCachedMessages: (messages: CometChat.BaseMessage[]) => { + // Render the cached page right away + }, + onServerMessages: (messages: CometChat.BaseMessage[]) => { + // Replace it with the server's page + }, + onError: (error: CometChat.CometChatException) => { + // Offline or failed — keep showing the cached page + }, + }) + ) + .catch(() => { + // Already handled in onError + }); + ``` + + + ```javascript + let UID = "UID"; + let limit = 30; + + let messagesRequest = new CometChat.MessagesRequestBuilder() + .setUID(UID) + .setLimit(limit) + .build(); + + messagesRequest + .fetchPrevious( + new CometChat.MessageFetchListener({ + onCachedMessages: (messages) => { + // Render the cached page right away + }, + onServerMessages: (messages) => { + // Replace it with the server's page + }, + onError: (error) => { + // Offline or failed — keep showing the cached page + }, + }) + ) + .catch(() => { + // Already handled in onError + }); + ``` + + + +### Conversations + + + + ```typescript + let conversationsRequest: CometChat.ConversationsRequest = + new CometChat.ConversationsRequestBuilder().setLimit(30).build(); + + conversationsRequest + .fetchNext( + new CometChat.ConversationFetchListener({ + onCachedConversations: (conversations: CometChat.Conversation[]) => { + // Render the cached list + }, + onServerConversations: (conversations: CometChat.Conversation[]) => { + // Replace it with the server's list + }, + onError: (error: CometChat.CometChatException) => { + // Offline or failed + }, + }) + ) + .catch(() => {}); + ``` + + + ```javascript + let conversationsRequest = new CometChat.ConversationsRequestBuilder() + .setLimit(30) + .build(); + + conversationsRequest + .fetchNext( + new CometChat.ConversationFetchListener({ + onCachedConversations: (conversations) => { + // Render the cached list + }, + onServerConversations: (conversations) => { + // Replace it with the server's list + }, + onError: (error) => { + // Offline or failed + }, + }) + ) + .catch(() => {}); + ``` + + + +### A Single Conversation + +`getConversation()` accepts a third argument. `onCachedConversation` receives nothing when the conversation is not cached. + + + + ```typescript + let conversationWith: string = "UID"; + let conversationType: string = "user"; + + CometChat.getConversation( + conversationWith, + conversationType, + new CometChat.SingleConversationFetchListener({ + onCachedConversation: (conversation?: CometChat.Conversation) => {}, + onServerConversation: (conversation: CometChat.Conversation) => {}, + onError: (error: CometChat.CometChatException) => {}, + }) + ).catch(() => {}); + ``` + + + ```javascript + CometChat.getConversation( + "UID", + "user", + new CometChat.SingleConversationFetchListener({ + onCachedConversation: (conversation) => {}, + onServerConversation: (conversation) => {}, + onError: (error) => {}, + }) + ).catch(() => {}); + ``` + + + +### Other Lists + +The same pattern works for these requests: + +| Request | Listener | Callbacks | +| --- | --- | --- | +| `UsersRequest`, `BlockedUsersRequest` | `CometChat.UserFetchListener` | `onCachedUsers` · `onServerUsers` · `onError` | +| `GroupsRequest` | `CometChat.GroupFetchListener` | `onCachedGroups` · `onServerGroups` · `onError` | +| `GroupMembersRequest` | `CometChat.GroupMemberFetchListener` | `onCachedGroupMembers` · `onServerGroupMembers` · `onError` | +| `BannedMembersRequest` | `CometChat.BannedMemberFetchListener` | `onCachedBannedMembers` · `onServerBannedMembers` · `onError` | +| `ReactionsRequest` | `CometChat.ReactionFetchListener` | `onCachedReactions` · `onServerReactions` · `onError` | +| `NotificationFeedRequest` | `CometChat.NotificationFeedFetchListener` | `onCachedNotificationFeedItems` · `onServerNotificationFeedItems` · `onError` | + +These lists are served from the cache only for a request that was loaded online before with the same filters. A list that has never been loaded online has nothing to show offline. + +### When the Cache Is Skipped + +The cache only answers a request when it can apply every filter on the request correctly. If a request uses a filter that only the server can evaluate — for example `setSearchKeyword()` — `onCached*` is not called and only the server answers. The cache phase is also skipped while offline support is not running. + +## Send Messages While Offline + +Pass a `MessageSentListener` as the second argument to `sendMessage()`, `sendMediaMessage()` or `sendCustomMessage()`. The listener has three callbacks: + +| Callback | When it fires | +| --- | --- | +| `onMessagePending(message)` | The message is saved in the outbox. Show it in the UI as pending. | +| `onMessageSent(message)` | The server accepted the message. Replace the pending copy with this one. | +| `onError(error)` | The send failed, or the device is offline (see below). | + + + + ```typescript + let receiverID: string = "UID"; + let receiverType: string = CometChat.RECEIVER_TYPE.USER; + let textMessage: CometChat.TextMessage = new CometChat.TextMessage( + receiverID, + "Hello", + receiverType + ); + + CometChat.sendMessage( + textMessage, + new CometChat.MessageSentListener({ + onMessagePending: (message: CometChat.BaseMessage) => { + // Show the message with a pending indicator + }, + onMessageSent: (message: CometChat.BaseMessage) => { + // Swap the pending copy for the sent message + }, + onError: (error: CometChat.CometChatException) => { + // Offline: the message is still queued and will be sent on reconnect + }, + }) + ).catch(() => { + // Already handled in the listener + }); + ``` + + + ```javascript + let receiverID = "UID"; + let receiverType = CometChat.RECEIVER_TYPE.USER; + let textMessage = new CometChat.TextMessage(receiverID, "Hello", receiverType); + + CometChat.sendMessage( + textMessage, + new CometChat.MessageSentListener({ + onMessagePending: (message) => { + // Show the message with a pending indicator + }, + onMessageSent: (message) => { + // Swap the pending copy for the sent message + }, + onError: (error) => { + // Offline: the message is still queued and will be sent on reconnect + }, + }) + ).catch(() => { + // Already handled in the listener + }); + ``` + + + +What happens depends on the connection: + +- **Online:** `onMessagePending`, then `onMessageSent`. The Promise resolves with the sent message. +- **Offline:** `onMessagePending`, then `onError` once with the code `FAILED_TO_FETCH`, and the Promise rejects. The message is **not** lost — it stays in the outbox and is sent after the connection returns, when `onMessageSent` fires. Do not resend it yourself, or the recipient receives it twice. +- **Outbox full:** with the default `REJECT_NEWEST` policy, the new send fails with `onError` and the Promise rejects. + + + Only sends that pass a `MessageSentListener` are queued. A send without a + listener behaves exactly as before: while offline, its Promise rejects and + the message is not saved. + + +Use `message.getLocalMessageId()` to match the pending message to the sent one. The SDK assigns this ID when the message is queued; it is separate from any `muid` you set. + +### Get Pending Messages + +`CometChat.getPendingMessages()` resolves with the messages that are still in the outbox. Use it to show queued messages again after a page reload. + + + + ```typescript + CometChat.getPendingMessages().then((messages: CometChat.BaseMessage[]) => { + console.log("Messages waiting to be sent:", messages); + }); + ``` + + + ```javascript + CometChat.getPendingMessages().then((messages) => { + console.log("Messages waiting to be sent:", messages); + }); + ``` + + + +It resolves with an empty list while offline support is not running. + +## Listen for Sync Events + +After a reconnect, the SDK runs a catch-up sync in two phases: conversations, then messages. Register a `SyncListener` to know when each phase starts, finishes or fails — for example, to refresh a screen once the sync is complete. + + + + ```typescript + let listenerID: string = "UNIQUE_LISTENER_ID"; + + CometChat.addSyncListener( + listenerID, + new CometChat.SyncListener({ + onConversationSyncStarted: () => {}, + onConversationSyncCompleted: () => { + // Re-fetch the conversation list + }, + onConversationSyncError: (error: CometChat.CometChatException) => {}, + onMessageSyncStarted: () => {}, + onMessageSyncCompleted: () => { + // Re-fetch the open message list + }, + onMessageSyncError: (error: CometChat.CometChatException) => {}, + }) + ); + + // Remove it when you no longer need it + CometChat.removeSyncListener(listenerID); + ``` + + + ```javascript + let listenerID = "UNIQUE_LISTENER_ID"; + + CometChat.addSyncListener( + listenerID, + new CometChat.SyncListener({ + onConversationSyncStarted: () => {}, + onConversationSyncCompleted: () => { + // Re-fetch the conversation list + }, + onConversationSyncError: (error) => {}, + onMessageSyncStarted: () => {}, + onMessageSyncCompleted: () => { + // Re-fetch the open message list + }, + onMessageSyncError: (error) => {}, + }) + ); + + // Remove it when you no longer need it + CometChat.removeSyncListener(listenerID); + ``` + + + +You can register a sync listener at any time, including before login. Registering the same ID again replaces the earlier listener. + +## Encrypt the Cache + +Set `encryption: true` to encrypt the cached data at rest. Encryption is off by default. + +```javascript +new CometChat.AppSettingsBuilder() + .setRegion("APP_REGION") + .setOfflineConfig({ enabled: true, encryption: true }) + .build(); +``` + +`CometChat.getOfflineEncryptionStatus()` reports what is actually in effect — `enabled` is what you asked for, and `atRest`, `keyStorage` and `cipherAvailable` describe what the SDK achieved. If encryption can't run, the SDK does not write an unencrypted cache; offline support stays off and the app works online only. + +In the browser, keep these limits in mind: + +- Encryption needs the Web Crypto API, so the page must be served from a secure origin (HTTPS or `localhost`). +- Message content is encrypted field by field, and the key is kept in the same browser storage as the data. This protects against casual inspection of the stored data, not against code running on your page or someone with access to the browser profile. +- Cached media files are not encrypted. Set `mediaCaching: CometChat.MediaCachingMode.OFF` if attachments must not be stored on the device. + +This is not end-to-end encryption; it only affects the copy stored on the device. + +## Logging Out and Switching Users + +The SDK deletes the local store — cached data, cached media and queued messages — when the user logs out. Queued messages are discarded without a callback. Logging in as a different user deletes the previous user's store before the new one opens. Do not clear the cache yourself on logout. + +## Limitations + +- The cache holds what your app has loaded while online, plus the changes picked up by the catch-up sync. Older history that was never loaded is not available offline. +- Only messages sent with a `MessageSentListener` are queued offline. Other actions — such as editing, deleting, reacting, pinning or marking as read — need a connection. +- Queued messages are discarded on logout. +- Cached data counts toward the browser's storage quota for your site, and the browser can clear it. + +--- + +## Next Steps + + + + Send text, media and custom messages + + + Listen for messages and fetch message history + + + Fetch and paginate the conversation list + + + Track the WebSocket connection + + diff --git a/ui-kit/angular/core-features.mdx b/ui-kit/angular/core-features.mdx index 912129e70..e90d1af9d 100644 --- a/ui-kit/angular/core-features.mdx +++ b/ui-kit/angular/core-features.mdx @@ -9,7 +9,7 @@ description: "Review CometChat Angular UI Kit core features for messaging, media | --- | --- | | Package | `@cometchat/chat-uikit-angular` | | Required setup | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` — must complete before rendering any component | -| Core features | Instant Messaging, Media Sharing, Read Receipts, Typing Indicator, User Presence, Reactions, Mentions, Rich Text Formatting, Quoted Reply, Pin & Save Messages, Search, Threaded Conversations, Thread Subscription, Moderation, Report Message, Group Chat | +| Core features | Instant Messaging, Media Sharing, Read Receipts, Typing Indicator, User Presence, Reactions, Mentions, Rich Text Formatting, Quoted Reply, Pin & Save Messages, Search, Threaded Conversations, Thread Subscription, Moderation, Report Message, Group Chat, Offline Support | | Key components | `CometChatConversations` → [Conversations](/ui-kit/angular/components/cometchat-conversations), `CometChatMessageList` → [Message List](/ui-kit/angular/components/cometchat-message-list), `CometChatMessageComposer` → [Message Composer](/ui-kit/angular/components/cometchat-message-composer), `CometChatMessageHeader` → [Message Header](/ui-kit/angular/components/cometchat-message-header), `CometChatUsers` → [Users](/ui-kit/angular/components/cometchat-users), `CometChatGroups` → [Groups](/ui-kit/angular/components/cometchat-groups), `CometChatGroupMembers` → [Group Members](/ui-kit/angular/components/cometchat-group-members) | | CSS class prefix | `.cometchat-` | | Theming | Override CSS variables on `.cometchat` class. See [Theming](/ui-kit/angular/customization/theming) | @@ -276,6 +276,16 @@ Conversation and Advanced Search enables users to quickly find conversations, me See the [Search Messages Guide](/ui-kit/angular/guides/search-messages) for detailed implementation instructions. +## Offline Support + +With offline support turned on, conversations and messages load from a cache on the device first and refresh from the server when it is reachable. Messages sent without a connection appear right away and are sent automatically when the device reconnects. Configure it with `setOfflineConfig()` on the `UIKitSettingsBuilder` — if you don't call it, the Angular UI Kit enables offline support with its defaults. See [Offline Support](/ui-kit/angular/offline-support) for setup and limitations. + +| Component | Functionality | +| --- | --- | +| [cometchat-conversations](/ui-kit/angular/components/cometchat-conversations) | Renders the cached conversation list immediately, then updates it with the server's list. | +| [cometchat-message-list](/ui-kit/angular/components/cometchat-message-list) | Opens a conversation with its cached messages and media, then updates it with the server's page. | +| [cometchat-message-composer](/ui-kit/angular/components/cometchat-message-composer) | Queues messages sent while offline; they are delivered automatically when the connection returns. | + --- ## Next Steps diff --git a/ui-kit/angular/llms-angular-v5.mdx b/ui-kit/angular/llms-angular-v5.mdx index 4be4c090f..11422b874 100644 --- a/ui-kit/angular/llms-angular-v5.mdx +++ b/ui-kit/angular/llms-angular-v5.mdx @@ -48,6 +48,7 @@ exhaustive inputs, long-tail components, theming tokens, or feature enablement. ## Core & configuration - [Core Features](/ui-kit/angular/core-features) +- [Offline Support](/ui-kit/angular/offline-support) - [Methods](/ui-kit/angular/methods) - [Events](/ui-kit/angular/events) - [Sound Manager](/ui-kit/angular/sound-manager) diff --git a/ui-kit/angular/offline-support.mdx b/ui-kit/angular/offline-support.mdx new file mode 100644 index 000000000..49b704441 --- /dev/null +++ b/ui-kit/angular/offline-support.mdx @@ -0,0 +1,110 @@ +--- +title: "Offline Support" +description: "Let the CometChat Angular UI Kit show cached conversations and messages without a network and send queued messages when the connection returns." +--- + + + +| Field | Value | +| --- | --- | +| Package | `@cometchat/chat-uikit-angular` | +| Enable | `new UIKitSettingsBuilder().setOfflineConfig({ enabled: true, ... })` before `CometChatUIKit.init(UIKitSettings)` | +| Disable | `setOfflineConfig({ enabled: false })` — if you don't call `setOfflineConfig()`, the Angular UI Kit turns offline support **on** with its defaults | +| Config | The object is passed to the JavaScript SDK's `AppSettingsBuilder.setOfflineConfig()` — options are listed in [JavaScript SDK Offline Support](/sdk/javascript/offline-support#configuration-options) | +| Runtime check | `CometChat.isOfflineEnabled()` from `@cometchat/chat-sdk-javascript` | +| Components that use the cache | `cometchat-conversations` → [Conversations](/ui-kit/angular/components/cometchat-conversations), `cometchat-message-list` → [Message List](/ui-kit/angular/components/cometchat-message-list), `cometchat-message-composer` → [Message Composer](/ui-kit/angular/components/cometchat-message-composer) | +| Component inputs | None — offline support is configured in UI Kit settings only | +| Not included | No offline banner and no "retry" action for a failed message | + + + +With offline support turned on, the UI Kit keeps showing the user's chats when the network drops. Conversations and messages load from a cache on the device first and are refreshed from the server when it is reachable, and messages sent while offline are delivered automatically once the connection returns. + +The UI Kit builds on the [offline support in the JavaScript SDK](/sdk/javascript/offline-support). You configure it in UI Kit settings; the components handle the rest. + +## Configure Offline Support + +Call `setOfflineConfig()` on the `UIKitSettingsBuilder` before `CometChatUIKit.init()`. Set `enabled` explicitly. + +```typescript +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-angular"; + +const UIKitSettings = new UIKitSettingsBuilder() + .setAppId("APP_ID") + .setRegion("REGION") + .setAuthKey("AUTH_KEY") + .subscribePresenceForAllUsers() + .setOfflineConfig({ + enabled: true, + mediaCaching: CometChat.MediaCachingMode.AUTO, + }) + .build(); + +CometChatUIKit.init(UIKitSettings)?.then(() => { + // login your user +}); +``` + +The UI Kit passes this object to the SDK, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. + + + If you don't call `setOfflineConfig()`, the Angular UI Kit enables offline + support with `mediaCaching` set to `AUTO`, which stores the user's + conversations, messages and media in the browser. To keep everything + online-only, turn it off explicitly: + + ```typescript + new UIKitSettingsBuilder() + // ... + .setOfflineConfig({ enabled: false }) + .build(); + ``` + + + + Whether offline support is actually running can change after init — for + example, CometChat can switch it off for your app from the server. The UI + Kit checks `CometChat.isOfflineEnabled()` each time it needs to; do the same + in your own code instead of reading back the value you configured. + + +## What Changes in the Components + +| Feature | Components | Behaviour | +| --- | --- | --- | +| Cached conversations | [Conversations](/ui-kit/angular/components/cometchat-conversations) | The list renders from the cache immediately, then updates with the server's list. Offline, the cached list stays on screen. | +| Cached messages | [Message List](/ui-kit/angular/components/cometchat-message-list) | A conversation opens with its cached messages, then updates with the server's page. | +| Sending while offline | [Message Composer](/ui-kit/angular/components/cometchat-message-composer), [Message List](/ui-kit/angular/components/cometchat-message-list) | A message sent offline appears in the list straight away and is queued. It is sent automatically when the connection returns, and its receipt updates as usual. | +| Cached media | [Message List](/ui-kit/angular/components/cometchat-message-list) | Images, videos, audio and files that were downloaded while online are shown from the device when offline (with `mediaCaching` set to `AUTO`). | +| Attachment uploads | [Message Composer](/ui-kit/angular/components/cometchat-message-composer) | A file that failed to upload can be retried, and staged attachments are restored when the user reopens the conversation. | + +## Logging Out + +The SDK deletes the cached data, cached media and any queued messages when the user logs out, and when a different user logs in. You don't need to clear anything yourself. + +## Limitations + +- The cache only holds what the user has loaded while online, plus the changes picked up when the device reconnects. A user who has never logged in online has nothing to show offline. +- Only sending messages works offline. Actions such as editing, deleting, reacting and pinning need a connection. +- Search reads from the server only, so it doesn't work while offline. +- There is no built-in offline banner and no "retry" action for a failed message. Use `CometChat.isOfflineEnabled()` and the SDK's [connection status](/sdk/javascript/connection-status) if you want to build your own. + +--- + +## Next Steps + + + + Configuration options, queued sends and sync events + + + See how the components power each chat feature + + + Customize how messages are rendered + + + Initialize, log in and send messages with the UI Kit + + diff --git a/ui-kit/react/core-features.mdx b/ui-kit/react/core-features.mdx index 98f123873..6941ff5a2 100644 --- a/ui-kit/react/core-features.mdx +++ b/ui-kit/react/core-features.mdx @@ -9,7 +9,7 @@ description: "Overview of CometChat React UI Kit core features, including messag | --- | --- | | Package | `@cometchat/chat-uikit-react` | | Required setup | Wrap app in `CometChatProvider` with valid credentials — must complete before rendering any component | -| Core features | Instant Messaging, Media Sharing, Read Receipts, Mark as Unread, Typing Indicator, User Presence, Reactions, Mentions, Quoted Reply, Pin & Save Messages, Search, Threaded Conversations, Moderation, Report Message, Group Chat | +| Core features | Instant Messaging, Media Sharing, Read Receipts, Mark as Unread, Typing Indicator, User Presence, Reactions, Mentions, Quoted Reply, Pin & Save Messages, Search, Threaded Conversations, Moderation, Report Message, Group Chat, Offline Support | | Key components | `CometChatConversations` → [Conversations](/ui-kit/react/components/conversations), `CometChatMessageList` → [Message List](/ui-kit/react/components/message-list), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/components/message-composer), `CometChatMessageHeader` → [Message Header](/ui-kit/react/components/message-header), `CometChatUsers` → [Users](/ui-kit/react/components/users), `CometChatGroups` → [Groups](/ui-kit/react/components/groups), `CometChatGroupMembers` → [Group Members](/ui-kit/react/components/group-members) | | CSS class prefix | `.cometchat-` | | Theming | Override CSS variables on `.cometchat` class. See [Theming](/ui-kit/react/theming) | @@ -304,6 +304,16 @@ Search requires wiring the result callbacks to navigation: handle `onConversatio See the [Groups](/ui-kit/react/components/groups) component page for details. +## Offline Support + +With offline support turned on, conversations and messages load from a cache on the device first and refresh from the server when it is reachable. Messages sent without a connection appear right away and are sent automatically when the device reconnects. Offline support is off by default — turn it on with `setOfflineConfig()` on the `UIKitSettingsBuilder`. See [Offline Support](/ui-kit/react/offline-support) for setup and limitations. + +| Components | Functionality | +| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| [Conversations](/ui-kit/react/components/conversations) | Renders the cached conversation list immediately, then updates it with the server's list. | +| [Message List](/ui-kit/react/components/message-list) | Opens a conversation with its cached messages and media, then updates it with the server's page. | +| [Message Composer](/ui-kit/react/components/message-composer) | Queues messages sent while offline; they are delivered automatically when the connection returns. | + --- ## Next Steps diff --git a/ui-kit/react/llms-react-v7.mdx b/ui-kit/react/llms-react-v7.mdx index d5ac71012..d3da84809 100644 --- a/ui-kit/react/llms-react-v7.mdx +++ b/ui-kit/react/llms-react-v7.mdx @@ -48,6 +48,7 @@ components, theming tokens, or feature enablement. ## Core & configuration - [CometChatProvider](/ui-kit/react/cometchat-provider) - [Core Features](/ui-kit/react/core-features) +- [Offline Support](/ui-kit/react/offline-support) - [Methods](/ui-kit/react/methods) - [Event System](/ui-kit/react/event-system) - [Sound Manager](/ui-kit/react/sound-manager) diff --git a/ui-kit/react/offline-support.mdx b/ui-kit/react/offline-support.mdx new file mode 100644 index 000000000..e322b68af --- /dev/null +++ b/ui-kit/react/offline-support.mdx @@ -0,0 +1,95 @@ +--- +title: "Offline Support" +description: "Let the CometChat React UI Kit show cached conversations and messages without a network and send queued messages when the connection returns." +--- + + + +| Field | Value | +| --- | --- | +| Package | `@cometchat/chat-uikit-react` | +| Enable | `new UIKitSettingsBuilder().setOfflineConfig({ enabled: true, ... })` before `CometChatUIKit.init(settings)` — offline support is **off by default** | +| Config | The object is passed unchanged to the JavaScript SDK's `AppSettingsBuilder.setOfflineConfig()` — options are listed in [JavaScript SDK Offline Support](/sdk/javascript/offline-support#configuration-options) | +| Runtime check | `CometChat.isOfflineEnabled()` from `@cometchat/chat-sdk-javascript` | +| Components that use the cache | `CometChatConversations` → [Conversations](/ui-kit/react/components/conversations), `CometChatMessageList` → [Message List](/ui-kit/react/components/message-list), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/components/message-composer) | +| Component props | None — offline support is turned on in UI Kit settings only | +| Not included | No offline banner and no "retry" action for a failed message | + + + +With offline support turned on, the UI Kit keeps showing the user's chats when the network drops. Conversations and messages load from a cache on the device first and are refreshed from the server when it is reachable, and messages sent while offline are delivered automatically once the connection returns. + +The UI Kit builds on the [offline support in the JavaScript SDK](/sdk/javascript/offline-support). You turn it on in UI Kit settings; the components handle the rest. + +## Enable Offline Support + +Call `setOfflineConfig()` on the `UIKitSettingsBuilder` before `CometChatUIKit.init()`. Set `enabled: true` explicitly. + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; + +const settings = new UIKitSettingsBuilder() + .setAppId("APP_ID") + .setRegion("REGION") + .setAuthKey("AUTH_KEY") + .subscribePresenceForAllUsers() + .setOfflineConfig({ + enabled: true, + mediaCaching: CometChat.MediaCachingMode.AUTO, + }) + .build(); + +CometChatUIKit.init(settings).then(() => { + console.log("Initialization completed with offline support"); +}); +``` + +The UI Kit passes this object to the SDK unchanged, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. If you don't call `setOfflineConfig()`, offline support stays off and the UI Kit works exactly as before. + + + Whether offline support is actually running can change after init — for + example, CometChat can switch it off for your app from the server. The UI + Kit checks `CometChat.isOfflineEnabled()` each time it needs to; do the same + in your own code instead of reading back the value you configured. + + +## What Changes in the Components + +| Feature | Components | Behaviour | +| --- | --- | --- | +| Cached conversations | [Conversations](/ui-kit/react/components/conversations) | The list renders from the cache immediately, then updates with the server's list. Offline, the cached list stays on screen. | +| Cached messages | [Message List](/ui-kit/react/components/message-list) | A conversation opens with its cached messages, then updates with the server's page. Scrolling up loads older cached messages while offline. | +| Sending while offline | [Message Composer](/ui-kit/react/components/message-composer), [Message List](/ui-kit/react/components/message-list) | A message sent offline appears in the list straight away and is queued. It is sent automatically when the connection returns, and its receipt updates as usual. | +| Cached media | [Message List](/ui-kit/react/components/message-list) | Images, videos, audio and files that were downloaded while online are shown from the device when offline (with `mediaCaching` set to `AUTO`, the default). | +| Attachment uploads | [Message Composer](/ui-kit/react/components/message-composer#multi-attachment-staging-tray) | A file that failed to upload can be retried from the staging tray, and staged attachments are restored when the user reopens the conversation. | + +## Logging Out + +The SDK deletes the cached data, cached media and any queued messages when the user logs out, and when a different user logs in. You don't need to clear anything yourself. + +## Limitations + +- The cache only holds what the user has loaded while online, plus the changes picked up when the device reconnects. A user who has never logged in online has nothing to show offline. +- Only sending messages works offline. Actions such as editing, deleting, reacting and pinning need a connection. +- Search reads from the server only, so it doesn't work while offline. +- There is no built-in offline banner and no "retry" action for a failed message. Use `CometChat.isOfflineEnabled()` and the SDK's [connection status](/sdk/javascript/connection-status) if you want to build your own. + +--- + +## Next Steps + + + + Configuration options, queued sends and sync events + + + See how the components power each chat feature + + + Customize how messages are rendered + + + Initialize, log in and send messages with the UI Kit + + From da5ea3ccab28bc02314dc3799fe79cbfbc6bd17f Mon Sep 17 00:00:00 2001 From: rajdubey Date: Fri, 16 Oct 2026 12:43:10 +0530 Subject: [PATCH 2/3] docs(offline): address review on the web offline pages - JS SDK: correct the `enabled` default. It is false when setOfflineConfig() is never called and true when an object omits it (resolveOfflineConfig). - JS SDK: onCachedConversation is not called when the conversation is not cached. - JS SDK: TypeScript/JavaScript tabs on the encryption snippet. - React UI Kit: note that the kit calls setOfflineConfig() without a guard, so an older JS SDK makes init() reject; note the object form turns offline on. - React UI Kit: drop the scroll-up-offline claim (Angular stops paging after the cached page, so it is not common). - Angular UI Kit: note the typeof guard, which ignores the setting (and the default) on an older SDK; note the object form turns offline on. Co-Authored-By: Claude Opus 5.5 --- sdk/javascript/offline-support.mdx | 32 ++++++++++++++++++++---------- ui-kit/angular/offline-support.mdx | 9 ++++++++- ui-kit/react/offline-support.mdx | 12 +++++++++-- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/sdk/javascript/offline-support.mdx b/sdk/javascript/offline-support.mdx index 055406074..6f018211a 100644 --- a/sdk/javascript/offline-support.mdx +++ b/sdk/javascript/offline-support.mdx @@ -35,7 +35,7 @@ Offline support is **opt-in**. Until you enable it, the SDK behaves exactly as i ## Enable Offline Support -Pass an offline configuration to `setOfflineConfig()` on the `AppSettingsBuilder`, then initialize the SDK as usual. Set `enabled: true` explicitly. +Pass an offline configuration to `setOfflineConfig()` on the `AppSettingsBuilder`, then initialize the SDK as usual. Passing a config object turns offline support on unless it sets `enabled: false`; setting `enabled` explicitly keeps your intent clear. @@ -104,7 +104,7 @@ Every option is optional. Anything you leave out uses its default. | Option | Type | Default | Description | | --- | --- | --- | --- | -| `enabled` | `boolean` | `false` | Turns offline support on. Nothing is stored on the device unless this is `true`. | +| `enabled` | `boolean` | `false` if you never call `setOfflineConfig()`; `true` if you pass an object that leaves it out | Turns offline support on. Passing any config object turns it on unless the object sets `enabled: false`. Nothing is stored on the device unless offline support is on. | | `maxPendingMessages` | `number` | `50` | How many messages the outbox can hold. Accepted range is 1–100. | | `pendingQueueOverflowPolicy` | `CometChat.PendingMessageOverflowPolicy` | `REJECT_NEWEST` | What happens when the outbox is full: `REJECT_NEWEST` rejects the new send, `DROP_OLDEST` removes the oldest queued message to make room. | | `autoSendPendingOnReconnect` | `boolean` | `true` | Sends queued messages automatically after a reconnect. It does not affect the catch-up sync. | @@ -256,7 +256,7 @@ The call still returns a Promise that settles with the server result, so handle ### A Single Conversation -`getConversation()` accepts a third argument. `onCachedConversation` receives nothing when the conversation is not cached. +`getConversation()` accepts a third argument. When the conversation is not cached, `onCachedConversation` is not called. @@ -268,7 +268,7 @@ The call still returns a Promise that settles with the server result, so handle conversationWith, conversationType, new CometChat.SingleConversationFetchListener({ - onCachedConversation: (conversation?: CometChat.Conversation) => {}, + onCachedConversation: (conversation: CometChat.Conversation) => {}, onServerConversation: (conversation: CometChat.Conversation) => {}, onError: (error: CometChat.CometChatException) => {}, }) @@ -472,12 +472,24 @@ You can register a sync listener at any time, including before login. Registerin Set `encryption: true` to encrypt the cached data at rest. Encryption is off by default. -```javascript -new CometChat.AppSettingsBuilder() - .setRegion("APP_REGION") - .setOfflineConfig({ enabled: true, encryption: true }) - .build(); -``` + + + ```typescript + let appSetting: CometChat.AppSettings = new CometChat.AppSettingsBuilder() + .setRegion("APP_REGION") + .setOfflineConfig({ enabled: true, encryption: true }) + .build(); + ``` + + + ```javascript + let appSetting = new CometChat.AppSettingsBuilder() + .setRegion("APP_REGION") + .setOfflineConfig({ enabled: true, encryption: true }) + .build(); + ``` + + `CometChat.getOfflineEncryptionStatus()` reports what is actually in effect — `enabled` is what you asked for, and `atRest`, `keyStorage` and `cipherAvailable` describe what the SDK achieved. If encryption can't run, the SDK does not write an unencrypted cache; offline support stays off and the app works online only. diff --git a/ui-kit/angular/offline-support.mdx b/ui-kit/angular/offline-support.mdx index 49b704441..871c360e0 100644 --- a/ui-kit/angular/offline-support.mdx +++ b/ui-kit/angular/offline-support.mdx @@ -46,7 +46,14 @@ CometChatUIKit.init(UIKitSettings)?.then(() => { }); ``` -The UI Kit passes this object to the SDK, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. +The UI Kit passes this object to the SDK, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. Any object you pass turns offline support on unless it sets `enabled: false`. + + + The UI Kit applies the offline configuration only when the installed + `@cometchat/chat-sdk-javascript` exposes `AppSettingsBuilder.setOfflineConfig()`. + With an older SDK the setting — including the default — is silently ignored + and the UI Kit works online only. + If you don't call `setOfflineConfig()`, the Angular UI Kit enables offline diff --git a/ui-kit/react/offline-support.mdx b/ui-kit/react/offline-support.mdx index e322b68af..530f6435f 100644 --- a/ui-kit/react/offline-support.mdx +++ b/ui-kit/react/offline-support.mdx @@ -45,7 +45,15 @@ CometChatUIKit.init(settings).then(() => { }); ``` -The UI Kit passes this object to the SDK unchanged, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. If you don't call `setOfflineConfig()`, offline support stays off and the UI Kit works exactly as before. +The UI Kit passes this object to the SDK unchanged, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. Any object you pass turns offline support on unless it sets `enabled: false`. If you don't call `setOfflineConfig()`, offline support stays off and the UI Kit works exactly as before. + + + `setOfflineConfig()` needs a version of `@cometchat/chat-sdk-javascript` + that includes offline support. The UI Kit calls the SDK's + `AppSettingsBuilder.setOfflineConfig()` without checking for it, so with an + older SDK `CometChatUIKit.init()` rejects with a `TypeError` instead of + ignoring the setting. + Whether offline support is actually running can change after init — for @@ -59,7 +67,7 @@ The UI Kit passes this object to the SDK unchanged, so it accepts every option i | Feature | Components | Behaviour | | --- | --- | --- | | Cached conversations | [Conversations](/ui-kit/react/components/conversations) | The list renders from the cache immediately, then updates with the server's list. Offline, the cached list stays on screen. | -| Cached messages | [Message List](/ui-kit/react/components/message-list) | A conversation opens with its cached messages, then updates with the server's page. Scrolling up loads older cached messages while offline. | +| Cached messages | [Message List](/ui-kit/react/components/message-list) | A conversation opens with its cached messages, then updates with the server's page. | | Sending while offline | [Message Composer](/ui-kit/react/components/message-composer), [Message List](/ui-kit/react/components/message-list) | A message sent offline appears in the list straight away and is queued. It is sent automatically when the connection returns, and its receipt updates as usual. | | Cached media | [Message List](/ui-kit/react/components/message-list) | Images, videos, audio and files that were downloaded while online are shown from the device when offline (with `mediaCaching` set to `AUTO`, the default). | | Attachment uploads | [Message Composer](/ui-kit/react/components/message-composer#multi-attachment-staging-tray) | A file that failed to upload can be retried from the staging tray, and staged attachments are restored when the user reopens the conversation. | From fa0a401c13b154d6659dd98d67ab63c8a2b4d356 Mon Sep 17 00:00:00 2001 From: rajdubey Date: Mon, 19 Oct 2026 21:53:22 +0530 Subject: [PATCH 3/3] docs(offline): complete and verify the web offline pages against the SDK and kits JavaScript SDK page: - List every OfflineConfig key with its real default and range, and show enabled: true explicitly instead of relying on the omitted-key default. - Add failed messages and retry (PENDING/SENDING/FAILED, retryMessage, retryAllFailedMessages), onMessagesSynced, and a reference table for forceSyncNow, getSyncState, getLastSyncTimestamp, getCacheSize, clearOfflineCache and the media methods. - Document encryptionFailureBehavior, correct the secure-context wording, add browser notes (iframes, multiple tabs) and an Electron section that is marked to publish only after the pending SDK fix. - Add a minimum-version placeholder. React and Angular UI Kit pages: - Show enabled: true explicitly, note that initFromSettings doesn't enable offline support, describe the sending indicator, and point to the SDK retry methods. Rephrase the Angular opt-out so it stays correct when the kit default changes. Add minimum-version placeholders. Co-Authored-By: Claude Opus 5.5 --- sdk/javascript/offline-support.mdx | 213 +++++++++++++++++++++++++++-- ui-kit/angular/core-features.mdx | 2 +- ui-kit/angular/offline-support.mdx | 30 ++-- ui-kit/react/offline-support.mdx | 13 +- 4 files changed, 227 insertions(+), 31 deletions(-) diff --git a/sdk/javascript/offline-support.mdx b/sdk/javascript/offline-support.mdx index 6f018211a..168c6fdcc 100644 --- a/sdk/javascript/offline-support.mdx +++ b/sdk/javascript/offline-support.mdx @@ -11,11 +11,12 @@ description: "Cache conversations and messages on the device, show them instantl | Package | `@cometchat/chat-sdk-javascript` | | Import | `import { CometChat } from "@cometchat/chat-sdk-javascript";` | | Enable | `new CometChat.AppSettingsBuilder().setOfflineConfig({ enabled: true, ... })` before `CometChat.init()` — offline support is **off by default** | -| Key methods | `CometChat.isOfflineEnabled()` · `CometChat.getPendingMessages()` · `CometChat.addSyncListener(name, listener)` / `CometChat.removeSyncListener(name)` · `CometChat.getOfflineEncryptionStatus()` | +| Key methods | `CometChat.isOfflineEnabled()` · `CometChat.getPendingMessages()` · `CometChat.retryMessage(message)` / `CometChat.retryAllFailedMessages()` · `CometChat.addSyncListener(name, listener)` / `CometChat.removeSyncListener(name)` · `CometChat.getOfflineEncryptionStatus()` · see [Other Offline Methods](#other-offline-methods) | | Two-phase reads | Pass a listener to `fetchPrevious()` / `fetchNext()` — e.g. `new CometChat.MessageFetchListener({ onCachedMessages, onServerMessages, onError })`; `CometChat.getConversation(with, type, new CometChat.SingleConversationFetchListener({...}))` | | Queued sends | Pass `new CometChat.MessageSentListener({ onMessagePending, onMessageSent, onError })` as the second argument of `sendMessage()` / `sendMediaMessage()` / `sendCustomMessage()` | | Offline send result | `onMessagePending` → `onError` (`FAILED_TO_FETCH`) and the Promise rejects, while the message stays queued → `onMessageSent` after reconnect. A send **without** a listener is not queued | -| Storage | Browser IndexedDB, one store per app ID and user, deleted on logout | +| Failed sends | Status `FAILED`; never retried automatically. Retry with `CometChat.retryMessage(message)` or `CometChat.retryAllFailedMessages()` | +| Storage | Browser IndexedDB (SQLite in a configured Electron app), one store per app ID and user, deleted on logout | | Constraints | Cached reads skip any request that uses a server-only filter such as `setSearchKeyword()`. Encryption is opt-in and covers the database only, not cached media | | Related | [Send a Message](/sdk/javascript/send-message) · [Receive a Message](/sdk/javascript/receive-message) · [Retrieve Conversations](/sdk/javascript/retrieve-conversations) · [Connection Status](/sdk/javascript/connection-status) | @@ -25,6 +26,9 @@ Offline support keeps a local copy of the logged-in user's conversations and mes Offline support is **opt-in**. Until you enable it, the SDK behaves exactly as it does today: nothing is stored on the device and every read goes to the server. +{/* TODO(release): replace vX.Y.Z with the first JavaScript SDK release that ships offline support. */} +Requires JavaScript SDK vX.Y.Z or later. + ## How It Works - **One local store per user.** The SDK keeps a separate store for each app ID and user, in the browser's IndexedDB. Logging out, or logging in as a different user, deletes the previous user's store. @@ -35,7 +39,7 @@ Offline support is **opt-in**. Until you enable it, the SDK behaves exactly as i ## Enable Offline Support -Pass an offline configuration to `setOfflineConfig()` on the `AppSettingsBuilder`, then initialize the SDK as usual. Passing a config object turns offline support on unless it sets `enabled: false`; setting `enabled` explicitly keeps your intent clear. +Pass an offline configuration to `setOfflineConfig()` on the `AppSettingsBuilder`, then initialize the SDK as usual. Always include `enabled: true`. @@ -100,17 +104,26 @@ The offline store opens when a user logs in (or an existing session is restored) ### Configuration Options -Every option is optional. Anything you leave out uses its default. +Set `enabled: true` to turn offline support on. Every other option is optional, and anything you leave out uses its default. The count limits accept the range shown; a value outside it, including `0`, is treated as the maximum. | Option | Type | Default | Description | | --- | --- | --- | --- | -| `enabled` | `boolean` | `false` if you never call `setOfflineConfig()`; `true` if you pass an object that leaves it out | Turns offline support on. Passing any config object turns it on unless the object sets `enabled: false`. Nothing is stored on the device unless offline support is on. | -| `maxPendingMessages` | `number` | `50` | How many messages the outbox can hold. Accepted range is 1–100. | -| `pendingQueueOverflowPolicy` | `CometChat.PendingMessageOverflowPolicy` | `REJECT_NEWEST` | What happens when the outbox is full: `REJECT_NEWEST` rejects the new send, `DROP_OLDEST` removes the oldest queued message to make room. | -| `autoSendPendingOnReconnect` | `boolean` | `true` | Sends queued messages automatically after a reconnect. It does not affect the catch-up sync. | +| `enabled` | `boolean` | `false` | Set `enabled: true` to turn offline support on. Nothing is stored on the device unless offline support is on. | +| `maxPendingMessages` | `number` | `50` | How many messages the outbox can hold. Range 1–100. | +| `pendingQueueOverflowPolicy` | `CometChat.PendingMessageOverflowPolicy` | `REJECT_NEWEST` | What happens when the outbox is full: `REJECT_NEWEST` rejects the new send, `DROP_OLDEST` marks the oldest queued message as failed to make room. | +| `autoSendPendingOnReconnect` | `boolean` | `true` | Sends queued messages automatically after a reconnect. When `false`, a queued message is sent only when you call `retryMessage()` for it or a new message is sent in the same conversation. It does not affect the catch-up sync. | | `mediaCaching` | `CometChat.MediaCachingMode` | `AUTO` | `AUTO` downloads attachments of fetched and received messages so they can be viewed offline. `OFF` caches the message and its attachment details but not the file itself. | | `maxMediaCacheSize` | `number` (bytes) | `524288000` (500 MB) | Space cached media may use. The least recently used files are removed first. `0` means no limit. | +| `maxStorageSize` | `number` (bytes) | `262144000` (250 MB) | Space the cached conversations and messages may use. The oldest messages are removed first. `0` means no limit. | +| `maxConversations` | `number` | `100` | How many conversations the cache keeps. The least recently used conversation is removed first, with its messages. Range 1–1000. | +| `maxMessagesPerConversation` | `number` | `500` | How many of the latest messages the cache keeps for each conversation. Range 1–1000. | +| `cacheDurationDays` | `number` (days) | `0` | Removes a cached conversation that has had no new message and hasn't been opened for this many days. `0` means no time limit. | +| `maxSnapshotQueries` | `number` | `100` | How many different list requests — users, groups, members and the other [lists](#other-lists), each with its own filters — are kept for offline use. The least recently used is removed first. Range 1–1000. | +| `snapshotTtlDays` | `number` (days) | `7` | How long a cached list request stays available offline. After that it returns nothing offline until it is loaded online again. `0` means no time limit. | | `encryption` | `boolean` | `false` | Encrypts the cached data at rest. See [Encrypt the Cache](#encrypt-the-cache). | +| `encryptionFailureBehavior` | `string` | `"ONLINE_ONLY"` | Applies only when `encryption` is `true` and encryption can't run on the device. `"ONLINE_ONLY"` opens no cache and the app works online only. `"PLAINTEXT_FALLBACK"` opens an unencrypted cache so offline support keeps working. | + +Messages waiting in the outbox, including failed ones, are never removed by these limits. ## Check Whether Offline Is Running @@ -378,7 +391,8 @@ What happens depends on the connection: - **Online:** `onMessagePending`, then `onMessageSent`. The Promise resolves with the sent message. - **Offline:** `onMessagePending`, then `onError` once with the code `FAILED_TO_FETCH`, and the Promise rejects. The message is **not** lost — it stays in the outbox and is sent after the connection returns, when `onMessageSent` fires. Do not resend it yourself, or the recipient receives it twice. -- **Outbox full:** with the default `REJECT_NEWEST` policy, the new send fails with `onError` and the Promise rejects. +- **Outbox full:** with the default `REJECT_NEWEST` policy, the new send fails with `onError` (code `QUEUE_FULL`), the Promise rejects and the message is not saved. +- **Rejected later:** if a queued message can't be sent once the connection is back, it is marked as failed. While the page that sent it is still open, `onError` is called again with the reason. See [Failed Messages and Retry](#failed-messages-and-retry). Only sends that pass a `MessageSentListener` are queued. A send without a @@ -390,7 +404,7 @@ Use `message.getLocalMessageId()` to match the pending message to the sent one. ### Get Pending Messages -`CometChat.getPendingMessages()` resolves with the messages that are still in the outbox. Use it to show queued messages again after a page reload. +`CometChat.getPendingMessages()` resolves with the messages that are still in the outbox, including failed ones. Pass a conversation ID (`message.getConversationId()`) to get only that conversation's messages. Use it to show queued messages again after a page reload. @@ -411,6 +425,56 @@ Use `message.getLocalMessageId()` to match the pending message to the sent one. It resolves with an empty list while offline support is not running. +### Failed Messages and Retry + +`message.getStatus()` on a message from the outbox returns one of these `CometChat.MessageStatus` values: + +| Status | Meaning | +| --- | --- | +| `PENDING` | Queued. It is sent automatically when the device is connected. | +| `SENDING` | Being sent now. | +| `FAILED` | It could not be sent. It stays in the outbox until you retry it. | + +A queued message becomes `FAILED` when: + +- the server rejects it — for example, the receiver can't be messaged, the request isn't allowed, or the rate limit is exceeded; +- the request keeps failing without a response from the server — the SDK retries it in the background a few times with an increasing delay first; +- it is dropped from a full outbox by the `DROP_OLDEST` policy. + +The SDK never retries a `FAILED` message on its own. Retry it from your UI, for example from a "tap to retry" action: + +| Method | Description | +| --- | --- | +| `CometChat.retryMessage(message: BaseMessage \| string, listener?: MessageSentListener): Promise` | Queues one message again. Pass the message, or its `getLocalMessageId()`. | +| `CometChat.retryAllFailedMessages(listener?: MessageSentListener): Promise` | Queues again every message that failed without a server response. Messages the server rejected, and messages dropped by `DROP_OLDEST`, are skipped; retry those one at a time with `retryMessage()`. | + + + + ```typescript + CometChat.getPendingMessages().then((messages: CometChat.BaseMessage[]) => { + messages + .filter((message) => message.getStatus() === CometChat.MessageStatus.FAILED) + .forEach((message) => { + CometChat.retryMessage(message); + }); + }); + ``` + + + ```javascript + CometChat.getPendingMessages().then((messages) => { + messages + .filter((message) => message.getStatus() === CometChat.MessageStatus.FAILED) + .forEach((message) => { + CometChat.retryMessage(message); + }); + }); + ``` + + + +A retried message is sent right away when the device is connected, and otherwise on the next reconnect. Read its status with `getPendingMessages()` to update your UI. + ## Listen for Sync Events After a reconnect, the SDK runs a catch-up sync in two phases: conversations, then messages. Register a `SyncListener` to know when each phase starts, finishes or fails — for example, to refresh a screen once the sync is complete. @@ -468,6 +532,74 @@ After a reconnect, the SDK runs a catch-up sync in two phases: conversations, th You can register a sync listener at any time, including before login. Registering the same ID again replaces the earlier listener. +### Updates Picked Up by the Sync + +The catch-up sync also tells your existing `MessageListener` what changed while the device was offline. Messages that are new to the device arrive through `onMessageReceived` as usual (for example `onTextMessageReceived`). Edits, deletions and other changes to messages that were already cached arrive together in `onMessagesSynced`. Update the matching messages in your UI by ID instead of appending them. + + + + ```typescript + CometChat.addMessageListener( + "UNIQUE_LISTENER_ID", + new CometChat.MessageListener({ + onMessagesSynced: (messages: CometChat.BaseMessage[]) => { + // Replace each message in your list by messages[i].getId() + }, + }) + ); + ``` + + + ```javascript + CometChat.addMessageListener( + "UNIQUE_LISTENER_ID", + new CometChat.MessageListener({ + onMessagesSynced: (messages) => { + // Replace each message in your list by messages[i].getId() + }, + }) + ); + ``` + + + +## Other Offline Methods + +| Method | Description | +| --- | --- | +| `CometChat.forceSyncNow(callback?: (error?: CometChatException) => void): void` | Starts a catch-up sync now. The callback is called with `null` when it completes, or with an error code: `ERROR_OFFLINE_SYNC_IN_PROGRESS`, `ERROR_OFFLINE_SYNC_COOLDOWN` (within 10 seconds of the previous forced sync; the error has `retryAfterMs`), `ERROR_OFFLINE_DISABLED` or `USER_NOT_LOGGED_IN`. It doesn't send queued messages. | +| `CometChat.getSyncState(): string` | `"SYNCING"` while a catch-up sync runs, otherwise `"IDLE"`. | +| `CometChat.getLastSyncTimestamp(): Promise` | When the last catch-up sync completed, in milliseconds, or `0` if none has. | +| `CometChat.getCacheSize(): Promise` | Size of the local cache in bytes. `0` while offline support is not running. | +| `CometChat.clearOfflineCache(): Promise` | Deletes the current user's cached data and cached media, **including queued and failed messages**, without a callback for them. You don't need it on logout; the SDK clears the store itself. | +| `CometChat.downloadMedia(attachment, callback?: MediaCallbackListener): void` | Downloads and caches an attachment, for example when `mediaCaching` is `OFF`. The callback has `onSuccess`, `onProgress(percent)` and `onError`. | +| `CometChat.getCachedMediaObjectURL(attachment): Promise` | A `blob:` URL for a cached attachment that you can use as an `` or ` -`CometChat.getOfflineEncryptionStatus()` reports what is actually in effect — `enabled` is what you asked for, and `atRest`, `keyStorage` and `cipherAvailable` describe what the SDK achieved. If encryption can't run, the SDK does not write an unencrypted cache; offline support stays off and the app works online only. +`CometChat.getOfflineEncryptionStatus()` reports what is actually in effect — `enabled` is what you asked for, and `atRest`, `keyStorage` and `cipherAvailable` describe what the SDK achieved. If encryption can't run on the device, the default `encryptionFailureBehavior` of `"ONLINE_ONLY"` keeps offline support off, so the app works online only and nothing unencrypted is written. Set it to `"PLAINTEXT_FALLBACK"` if you prefer an unencrypted cache in that case; `atRest` then reports `"NONE"`. In the browser, keep these limits in mind: -- Encryption needs the Web Crypto API, so the page must be served from a secure origin (HTTPS or `localhost`). +- Encryption needs the Web Crypto API, which browsers provide only in a secure context: a page served over HTTPS, from `localhost`, or opened from a `file://` URL. On a plain `http://` address such as a LAN IP, encryption can't run. - Message content is encrypted field by field, and the key is kept in the same browser storage as the data. This protects against casual inspection of the stored data, not against code running on your page or someone with access to the browser profile. -- Cached media files are not encrypted. Set `mediaCaching: CometChat.MediaCachingMode.OFF` if attachments must not be stored on the device. +- Cached media files are not encrypted. Set `mediaCaching: CometChat.MediaCachingMode.OFF` to stop caching received attachments; attachments you send are still stored until they are sent. This is not end-to-end encryption; it only affects the copy stored on the device. @@ -512,6 +644,61 @@ The SDK deletes the local store — cached data, cached media and queued message - Queued messages are discarded on logout. - Cached data counts toward the browser's storage quota for your site, and the browser can clear it. +## Browser Notes + +- **Iframes.** Some browsers, including Safari, partition storage by the top-level site. If your chat runs in an iframe embedded on another site, its cache is separate from the cache of the same app opened directly. An iframe sandboxed without `allow-same-origin` has no access to storage, and the SDK can't run there. +- **Multiple tabs.** All tabs of your app on the same site share one local store. If several tabs are open when the connection returns, a message queued while offline can occasionally be delivered more than once. + +## Electron + +{/* TODO(release): publish this section only after the SDK's Electron IPC path-validation fix ships. Remove this comment and the section if that fix is not in the release. */} + +In an Electron app, the SDK can store the cache in an SQLite database and cached media as files in the app's user data folder, instead of in IndexedDB. Set it up in the main process and the preload script: + +1. Install `better-sqlite3-multiple-ciphers`, built for your Electron version. It is required for SQLite storage and for encryption. Without it, the SDK uses IndexedDB, as in a browser; with `encryption: true`, `encryptionFailureBehavior` decides what happens. +2. In the main process, call `registerOfflineIpc()` once the app is ready, and create the window with `contextIsolation: true`. +3. In the preload script, call `installCometChatBridge()`. + + + + ```javascript + const { app, BrowserWindow } = require("electron"); + const path = require("path"); + const { registerOfflineIpc } = require("@cometchat/chat-sdk-javascript/electron/main"); + + app.whenReady().then(() => { + registerOfflineIpc(); + + new BrowserWindow({ + webPreferences: { + preload: path.join(__dirname, "preload.js"), + contextIsolation: true, + nodeIntegration: false, + sandbox: false, // or bundle the preload script; see the note below + }, + }); + }); + ``` + + + ```javascript + const { installCometChatBridge } = require("@cometchat/chat-sdk-javascript/electron/preload"); + + installCometChatBridge(); + ``` + + + + + Electron sandboxes the preload script by default (`sandbox: true`), and a + sandboxed preload can't load modules from `node_modules`. Either set + `sandbox: false` for the window, or bundle your preload script, including + the SDK's preload module, into a single file. If the preload doesn't load, + the SDK falls back to IndexedDB. + + +With encryption on, the whole SQLite database is encrypted and its key is protected by the operating system's key store. On Linux this needs a keyring service; without one, encryption can't run. + --- ## Next Steps diff --git a/ui-kit/angular/core-features.mdx b/ui-kit/angular/core-features.mdx index e90d1af9d..065538b1b 100644 --- a/ui-kit/angular/core-features.mdx +++ b/ui-kit/angular/core-features.mdx @@ -278,7 +278,7 @@ See the [Search Messages Guide](/ui-kit/angular/guides/search-messages) for deta ## Offline Support -With offline support turned on, conversations and messages load from a cache on the device first and refresh from the server when it is reachable. Messages sent without a connection appear right away and are sent automatically when the device reconnects. Configure it with `setOfflineConfig()` on the `UIKitSettingsBuilder` — if you don't call it, the Angular UI Kit enables offline support with its defaults. See [Offline Support](/ui-kit/angular/offline-support) for setup and limitations. +With offline support turned on, conversations and messages load from a cache on the device first and refresh from the server when it is reachable. Messages sent without a connection appear right away and are sent automatically when the device reconnects. Turn it on with `setOfflineConfig({ enabled: true })` on the `UIKitSettingsBuilder`. See [Offline Support](/ui-kit/angular/offline-support) for setup and limitations. | Component | Functionality | | --- | --- | diff --git a/ui-kit/angular/offline-support.mdx b/ui-kit/angular/offline-support.mdx index 871c360e0..ff1038423 100644 --- a/ui-kit/angular/offline-support.mdx +++ b/ui-kit/angular/offline-support.mdx @@ -9,12 +9,12 @@ description: "Let the CometChat Angular UI Kit show cached conversations and mes | --- | --- | | Package | `@cometchat/chat-uikit-angular` | | Enable | `new UIKitSettingsBuilder().setOfflineConfig({ enabled: true, ... })` before `CometChatUIKit.init(UIKitSettings)` | -| Disable | `setOfflineConfig({ enabled: false })` — if you don't call `setOfflineConfig()`, the Angular UI Kit turns offline support **on** with its defaults | +| Disable | `setOfflineConfig({ enabled: false })` — set it explicitly to keep the UI Kit online-only | | Config | The object is passed to the JavaScript SDK's `AppSettingsBuilder.setOfflineConfig()` — options are listed in [JavaScript SDK Offline Support](/sdk/javascript/offline-support#configuration-options) | | Runtime check | `CometChat.isOfflineEnabled()` from `@cometchat/chat-sdk-javascript` | | Components that use the cache | `cometchat-conversations` → [Conversations](/ui-kit/angular/components/cometchat-conversations), `cometchat-message-list` → [Message List](/ui-kit/angular/components/cometchat-message-list), `cometchat-message-composer` → [Message Composer](/ui-kit/angular/components/cometchat-message-composer) | | Component inputs | None — offline support is configured in UI Kit settings only | -| Not included | No offline banner and no "retry" action for a failed message | +| Not included | No offline banner and no "retry" action for a failed message. Use the SDK's [`CometChat.retryMessage()`](/sdk/javascript/offline-support#failed-messages-and-retry) to build one | @@ -22,9 +22,12 @@ With offline support turned on, the UI Kit keeps showing the user's chats when t The UI Kit builds on the [offline support in the JavaScript SDK](/sdk/javascript/offline-support). You configure it in UI Kit settings; the components handle the rest. +{/* TODO(release): replace vX.Y.Z with the first Angular UI Kit and JavaScript SDK releases that ship offline support. */} +Requires Angular UI Kit vX.Y.Z or later and JavaScript SDK vX.Y.Z or later. + ## Configure Offline Support -Call `setOfflineConfig()` on the `UIKitSettingsBuilder` before `CometChatUIKit.init()`. Set `enabled` explicitly. +Call `setOfflineConfig()` on the `UIKitSettingsBuilder` before `CometChatUIKit.init()`. Always include `enabled: true`. ```typescript import { CometChat } from "@cometchat/chat-sdk-javascript"; @@ -46,20 +49,21 @@ CometChatUIKit.init(UIKitSettings)?.then(() => { }); ``` -The UI Kit passes this object to the SDK, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. Any object you pass turns offline support on unless it sets `enabled: false`. +The UI Kit passes this object to the SDK, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. + +Offline support is configured only through `CometChatUIKit.init()` with `UIKitSettings`. Initializing with `CometChatUIKit.initFromSettings()` doesn't turn it on. The UI Kit applies the offline configuration only when the installed `@cometchat/chat-sdk-javascript` exposes `AppSettingsBuilder.setOfflineConfig()`. - With an older SDK the setting — including the default — is silently ignored - and the UI Kit works online only. + With an older SDK the setting is silently ignored and the UI Kit works + online only. - If you don't call `setOfflineConfig()`, the Angular UI Kit enables offline - support with `mediaCaching` set to `AUTO`, which stores the user's - conversations, messages and media in the browser. To keep everything - online-only, turn it off explicitly: + To keep the UI Kit online-only, so that no conversations, messages or media + are stored in the browser, turn offline support off explicitly instead of + leaving out `setOfflineConfig()`: ```typescript new UIKitSettingsBuilder() @@ -82,8 +86,8 @@ The UI Kit passes this object to the SDK, so it accepts every option in the [SDK | --- | --- | --- | | Cached conversations | [Conversations](/ui-kit/angular/components/cometchat-conversations) | The list renders from the cache immediately, then updates with the server's list. Offline, the cached list stays on screen. | | Cached messages | [Message List](/ui-kit/angular/components/cometchat-message-list) | A conversation opens with its cached messages, then updates with the server's page. | -| Sending while offline | [Message Composer](/ui-kit/angular/components/cometchat-message-composer), [Message List](/ui-kit/angular/components/cometchat-message-list) | A message sent offline appears in the list straight away and is queued. It is sent automatically when the connection returns, and its receipt updates as usual. | -| Cached media | [Message List](/ui-kit/angular/components/cometchat-message-list) | Images, videos, audio and files that were downloaded while online are shown from the device when offline (with `mediaCaching` set to `AUTO`). | +| Sending while offline | [Message Composer](/ui-kit/angular/components/cometchat-message-composer), [Message List](/ui-kit/angular/components/cometchat-message-list) | A message sent offline appears in the list straight away with the sending (clock) indicator, and is queued. It is sent automatically when the connection returns, and its receipt then updates as usual. | +| Cached media | [Message List](/ui-kit/angular/components/cometchat-message-list) | Images, videos, audio and files that were downloaded while online are shown from the device when offline (with `mediaCaching` set to `AUTO`, the SDK default). | | Attachment uploads | [Message Composer](/ui-kit/angular/components/cometchat-message-composer) | A file that failed to upload can be retried, and staged attachments are restored when the user reopens the conversation. | ## Logging Out @@ -95,7 +99,7 @@ The SDK deletes the cached data, cached media and any queued messages when the u - The cache only holds what the user has loaded while online, plus the changes picked up when the device reconnects. A user who has never logged in online has nothing to show offline. - Only sending messages works offline. Actions such as editing, deleting, reacting and pinning need a connection. - Search reads from the server only, so it doesn't work while offline. -- There is no built-in offline banner and no "retry" action for a failed message. Use `CometChat.isOfflineEnabled()` and the SDK's [connection status](/sdk/javascript/connection-status) if you want to build your own. +- There is no built-in offline banner and no "retry" action for a failed message. A message that fails is never retried automatically. To build your own, use the SDK's [connection status](/sdk/javascript/connection-status) listener, and [`CometChat.getPendingMessages()` and `CometChat.retryMessage()`](/sdk/javascript/offline-support#failed-messages-and-retry). --- diff --git a/ui-kit/react/offline-support.mdx b/ui-kit/react/offline-support.mdx index 530f6435f..36096a98d 100644 --- a/ui-kit/react/offline-support.mdx +++ b/ui-kit/react/offline-support.mdx @@ -13,7 +13,7 @@ description: "Let the CometChat React UI Kit show cached conversations and messa | Runtime check | `CometChat.isOfflineEnabled()` from `@cometchat/chat-sdk-javascript` | | Components that use the cache | `CometChatConversations` → [Conversations](/ui-kit/react/components/conversations), `CometChatMessageList` → [Message List](/ui-kit/react/components/message-list), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/components/message-composer) | | Component props | None — offline support is turned on in UI Kit settings only | -| Not included | No offline banner and no "retry" action for a failed message | +| Not included | No offline banner and no "retry" action for a failed message. Use the SDK's [`CometChat.retryMessage()`](/sdk/javascript/offline-support#failed-messages-and-retry) to build one | @@ -21,6 +21,9 @@ With offline support turned on, the UI Kit keeps showing the user's chats when t The UI Kit builds on the [offline support in the JavaScript SDK](/sdk/javascript/offline-support). You turn it on in UI Kit settings; the components handle the rest. +{/* TODO(release): replace vX.Y.Z with the first React UI Kit and JavaScript SDK releases that ship offline support. */} +Requires React UI Kit vX.Y.Z or later and JavaScript SDK vX.Y.Z or later. + ## Enable Offline Support Call `setOfflineConfig()` on the `UIKitSettingsBuilder` before `CometChatUIKit.init()`. Set `enabled: true` explicitly. @@ -45,7 +48,9 @@ CometChatUIKit.init(settings).then(() => { }); ``` -The UI Kit passes this object to the SDK unchanged, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. Any object you pass turns offline support on unless it sets `enabled: false`. If you don't call `setOfflineConfig()`, offline support stays off and the UI Kit works exactly as before. +The UI Kit passes this object to the SDK unchanged, so it accepts every option in the [SDK configuration table](/sdk/javascript/offline-support#configuration-options) — the outbox size, media caching, encryption and so on. Always include `enabled: true`. If you don't call `setOfflineConfig()`, offline support stays off and the UI Kit works exactly as before. + +Offline support is configured only through `CometChatUIKit.init()` with `UIKitSettings`. Initializing with `CometChatUIKit.initFromSettings()` doesn't turn it on. `setOfflineConfig()` needs a version of `@cometchat/chat-sdk-javascript` @@ -68,7 +73,7 @@ The UI Kit passes this object to the SDK unchanged, so it accepts every option i | --- | --- | --- | | Cached conversations | [Conversations](/ui-kit/react/components/conversations) | The list renders from the cache immediately, then updates with the server's list. Offline, the cached list stays on screen. | | Cached messages | [Message List](/ui-kit/react/components/message-list) | A conversation opens with its cached messages, then updates with the server's page. | -| Sending while offline | [Message Composer](/ui-kit/react/components/message-composer), [Message List](/ui-kit/react/components/message-list) | A message sent offline appears in the list straight away and is queued. It is sent automatically when the connection returns, and its receipt updates as usual. | +| Sending while offline | [Message Composer](/ui-kit/react/components/message-composer), [Message List](/ui-kit/react/components/message-list) | A message sent offline from the composer appears in the list straight away with the sending (clock) indicator, and is queued. It is sent automatically when the connection returns, and its receipt then updates as usual. | | Cached media | [Message List](/ui-kit/react/components/message-list) | Images, videos, audio and files that were downloaded while online are shown from the device when offline (with `mediaCaching` set to `AUTO`, the default). | | Attachment uploads | [Message Composer](/ui-kit/react/components/message-composer#multi-attachment-staging-tray) | A file that failed to upload can be retried from the staging tray, and staged attachments are restored when the user reopens the conversation. | @@ -81,7 +86,7 @@ The SDK deletes the cached data, cached media and any queued messages when the u - The cache only holds what the user has loaded while online, plus the changes picked up when the device reconnects. A user who has never logged in online has nothing to show offline. - Only sending messages works offline. Actions such as editing, deleting, reacting and pinning need a connection. - Search reads from the server only, so it doesn't work while offline. -- There is no built-in offline banner and no "retry" action for a failed message. Use `CometChat.isOfflineEnabled()` and the SDK's [connection status](/sdk/javascript/connection-status) if you want to build your own. +- There is no built-in offline banner and no "retry" action for a failed message. A message that fails is never retried automatically. To build your own, use the SDK's [connection status](/sdk/javascript/connection-status) listener, and [`CometChat.getPendingMessages()` and `CometChat.retryMessage()`](/sdk/javascript/offline-support#failed-messages-and-retry). ---