diff --git a/docs.json b/docs.json
index a525c7fae..741db403e 100644
--- a/docs.json
+++ b/docs.json
@@ -1856,7 +1856,6 @@
"pages": [
"ui-kit/android/guide-overview",
"ui-kit/android/guide-threaded-messages",
- "ui-kit/android/guide-thread-subscription",
"ui-kit/android/guide-pin-and-save-messages",
"ui-kit/android/guide-block-unblock-user",
"ui-kit/android/guide-new-chat",
@@ -6939,6 +6938,10 @@
}
},
"redirects": [
+ {
+ "source": "/ui-kit/android/guide-thread-subscription",
+ "destination": "/ui-kit/android/guide-threaded-messages#thread-subscription"
+ },
{
"source": "/sdk/flutter/group-kick-member",
"destination": "/sdk/flutter/group-kick-ban-members"
diff --git a/ui-kit/android/core-features.mdx b/ui-kit/android/core-features.mdx
index 3bf9d7ec0..1291e3e74 100644
--- a/ui-kit/android/core-features.mdx
+++ b/ui-kit/android/core-features.mdx
@@ -169,6 +169,7 @@ Rich Text Formatting allows users to style their messages with bold, italic, str
| --- | --- |
| [CometChatMessageComposer](/ui-kit/android/message-composer) | Provides a built-in rich text editor with formatting toolbar and text selection menu items for bold, italic, strikethrough, code, links, lists, blockquotes, and code blocks. |
| [CometChatMessageList](/ui-kit/android/message-list) | Renders formatted messages with the appropriate styling automatically applied, ensuring that rich text formatting is displayed exactly as intended by the sender. |
+
## Threaded Conversations
Respond directly to a specific message, keeping conversations organized.
@@ -183,16 +184,16 @@ Respond directly to a specific message, keeping conversations organized.
| [CometChatMessageComposer](/ui-kit/android/message-composer) | Allows composing messages within a thread. |
| [CometChatMessageList](/ui-kit/android/message-list) | Displays threaded messages in context. |
-## Thread Subscription
+### Thread Subscription
-Let users subscribe to or unsubscribe from a thread to control whether its replies notify them. Opt-in feature — enable it with `UIKitSettings.setEnableThreadSubscription(true)`.
+Let users subscribe to or unsubscribe from a thread to control whether its replies notify them. Enabled by default — remove a surface with `setThreadSubscriptionOptionVisibility(View.GONE)` or `setThreadSubscriptionVisibility(View.GONE)`.
| Component | Role |
| --- | --- |
| [CometChatMessageList](/ui-kit/android/message-list) | Provides the Subscribe to thread / Unsubscribe from thread option in the message action sheet. |
| [CometChatThreadHeader](/ui-kit/android/threaded-messages-header) | Shows the subscription bell on the thread view. |
-See the [Thread Subscription guide](/ui-kit/android/guide-thread-subscription) for setup and behavior.
+See [Threaded Messages → Thread Subscription](/ui-kit/android/guide-threaded-messages#thread-subscription) for setup and behavior.
## Quoted Replies
diff --git a/ui-kit/android/events.mdx b/ui-kit/android/events.mdx
index a4a18ea62..a08ad343d 100644
--- a/ui-kit/android/events.mdx
+++ b/ui-kit/android/events.mdx
@@ -190,7 +190,7 @@ lifecycleScope.launch {
}
```
-See the [Thread Subscription guide](/ui-kit/android/guide-thread-subscription) for the feature end to end.
+See [Threaded Messages → Thread Subscription](/ui-kit/android/guide-threaded-messages#thread-subscription) for the feature end to end.
### Call Events
diff --git a/ui-kit/android/guide-thread-subscription.mdx b/ui-kit/android/guide-thread-subscription.mdx
deleted file mode 100644
index 62f47b73f..000000000
--- a/ui-kit/android/guide-thread-subscription.mdx
+++ /dev/null
@@ -1,157 +0,0 @@
----
-title: "Thread Subscription"
-sidebarTitle: "Thread Subscription"
-description: "Let users subscribe to or unsubscribe from message threads so notifications only reach the people who care."
----
-
-## Overview
-
-Thread subscription gives users Slack-style control over thread noise: they can **subscribe** to a thread to be notified about its replies, or **unsubscribe** from one to mute it. Users are automatically subscribed when they start a thread, reply in one, or are @-mentioned in one — subscribing explicitly is how they opt in to a conversation they haven't participated in yet.
-
-The UI Kit ships two surfaces for the same toggle, kept in sync automatically:
-
-1. A **Subscribe to thread / Unsubscribe from thread** option in the message action sheet.
-2. A **subscription bell** on the thread view.
-
-## Prerequisites
-
-- Threaded messages working in your app — see [Threaded Messages](/ui-kit/android/guide-threaded-messages).
-- CometChat UI Kit for Android with Chat SDK v5 or later.
-
-## Enable the Feature
-
-Thread subscription is **off by default** and is enabled per app via `UIKitSettings` at init time. When the gate is off, neither surface renders and no subscription request is ever made.
-
-
-
-```kotlin lines
-val uiKitSettings = UIKitSettings.UIKitSettingsBuilder()
- .setAppId(APP_ID)
- .setRegion(REGION)
- .setAuthKey(AUTH_KEY)
- .setEnableThreadSubscription(true) // opt in — default is false
- .subscribePresenceForAllUsers()
- .build()
-
-CometChatUIKit.init(this, uiKitSettings, object : CometChat.CallbackListener() {
- override fun onSuccess(successString: String?) { }
- override fun onError(e: CometChatException?) { }
-})
-```
-
-
-
-Anywhere you build your own UI around the feature, check the gate with:
-
-```kotlin lines
-if (CometChatUIKit.isThreadSubscriptionEnabled()) {
- // render your subscription control / entry point
-}
-```
-
-## Surface 1: The Message Action Sheet Option
-
-With the gate on, [CometChatMessageList](/ui-kit/android/message-list) automatically adds a **Subscribe to thread** / **Unsubscribe from thread** option to the long-press action sheet. The label reflects the current state, and the option appears on regular messages of every type (agent messages and moderation-blocked messages are excluded) — on a thread reply it targets the thread's root message, so subscribing from anywhere in the thread works.
-
-To hide the option while keeping the rest of the feature:
-
-
-
-```kotlin lines
-messageList.setThreadSubscriptionOptionVisibility(View.GONE)
-```
-
-
-
-## Surface 2: The Thread Header Bell
-
-[CometChatThreadHeader](/ui-kit/android/threaded-messages-header) renders a subscription bell as a trailing control on the reply-count bar. It flips optimistically on tap and reverts with a toast if the request fails.
-
-
-
-```kotlin lines
-// Hide the bell (e.g. because you host your own — see below)
-threadHeader.setThreadSubscriptionVisibility(View.GONE)
-
-// Observe state changes (isSubscribed = the new state)
-threadHeader.setOnThreadSubscriptionChange { isSubscribed ->
- Log.d(TAG, "Thread subscribed: $isSubscribed")
-}
-```
-
-The visibility can also be set in XML with the `app:cometchatThreadSubscriptionVisibility` attribute.
-
-
-
-```kotlin lines
-CometChatThreadHeader(
- parentMessage = parentMessage,
- hideThreadSubscription = false, // hide the built-in bell when true
- isSubscribed = null, // null = seed from parentMessage.isThreadSubscribed()
- onSubscriptionToggle = { isSubscribed ->
- Log.d(TAG, "Thread subscribed: $isSubscribed")
- },
- threadSubscriptionView = null // or your own composable replacing the bell
-)
-```
-
-
-
-### Hosting the Bell in Your Own Top Bar
-
-Many apps (matching the CometChat sample apps and Figma) place the subscription bell in the thread screen's **top title bar** rather than the reply-count row. In Compose, the bell is available as a standalone public composable — hide the header's built-in one and host `ThreadSubscriptionBell` wherever you like:
-
-
-
-```kotlin lines
-TopAppBar(
- title = { Text(stringResource(R.string.thread)) },
- actions = {
- if (CometChatUIKit.isThreadSubscriptionEnabled()) {
- ThreadSubscriptionBell(parentMessage = parentMessage)
- }
- }
-)
-
-CometChatThreadHeader(
- parentMessage = parentMessage,
- hideThreadSubscription = true // the bell lives in the top bar instead
-)
-```
-
-
-```kotlin lines
-// Hide the kit header's bell and drive your own ImageView in the activity's title bar:
-threadHeader.setThreadSubscriptionVisibility(View.GONE)
-
-// On tap: flip your icon optimistically, then call the SDK
-CometChat.subscribeToThread(parentMessage.id, object : CometChat.CallbackListener() {
- override fun onSuccess(response: String?) { }
- override fun onError(e: CometChatException?) {
- // revert the icon and show a toast
- }
-})
-```
-
-
-
-## Behavior
-
-- **Optimistic with revert** — both surfaces flip instantly on tap, keep one request in flight per thread, and revert with a toast if the server rejects the change. An offline tap fails visibly and reverts; nothing is queued.
-- **Auto-subscribe on reply** — sending a reply in a thread subscribes the user, and every surface flips to the subscribed state automatically.
-- **Unsubscribing is not sticky** — replying again, or being @-mentioned, re-subscribes the user.
-- **Unknown state renders as unsubscribed** — a message whose subscription state hasn't been learned yet (for example, one that just arrived in real time) shows the enabled subscribe control, never a spinner.
-
-## Cross-Surface Sync
-
-Both surfaces observe the UI Kit event bus, so toggling in one place updates the other without a refetch. If you build your own subscription control, emit and collect `CometChatThreadEvent` through `CometChatEvents.threadEvents` — see [Events](/ui-kit/android/events).
-
-## Notifications
-
-Whether a subscribed thread actually produces a push notification is governed by the user's notification preferences: the replies preference supports notifying only for **threads the user is subscribed to** (`SUBSCRIBE_TO_SUBSCRIBED_THREADS`). See [Thread Subscription (SDK)](/sdk/android/v5/thread-subscription#notification-preferences).
-
-## Next Steps & Further Reading
-
-- [Thread Subscription (SDK)](/sdk/android/v5/thread-subscription) — the underlying APIs, including fetching the threads a user participates in to build a thread inbox.
-- [Threaded Messages Header](/ui-kit/android/threaded-messages-header) — the full component reference.
-- [Message List](/ui-kit/android/message-list) — action-sheet options.
diff --git a/ui-kit/android/guide-threaded-messages.mdx b/ui-kit/android/guide-threaded-messages.mdx
index 900ed3bd7..b2e60268e 100644
--- a/ui-kit/android/guide-threaded-messages.mdx
+++ b/ui-kit/android/guide-threaded-messages.mdx
@@ -274,6 +274,114 @@ if (user.isBlockedByMe) {
| Blocked User | Composer hidden; unblock layout shown. |
| Not in Group | Show option to join group first. |
+## Thread Subscription
+
+Thread subscription gives users Slack-style control over thread noise: they can **subscribe** to a thread to be notified about its replies, or **unsubscribe** from one to mute it. Users are automatically subscribed when they start a thread, reply in one, or are @-mentioned in one — subscribing explicitly is how they opt in to a conversation they haven't participated in yet.
+
+The UI Kit ships two surfaces for the same toggle, wired out of the box and kept in sync automatically:
+
+1. A **Subscribe to thread / Unsubscribe from thread** option in the message action sheet.
+2. A **subscription bell** on the thread view.
+
+### The Message Action Sheet Option
+
+[CometChatMessageList](/ui-kit/android/message-list) adds a **Subscribe to thread** / **Unsubscribe from thread** option to the long-press action sheet. The label reflects the current state, and the option appears on regular messages of every type (agent messages and moderation-blocked messages are excluded) — on a thread reply it targets the thread's root message, so subscribing from anywhere in the thread works.
+
+To hide the option while keeping the rest of the feature:
+
+
+
+```kotlin lines
+messageList.setThreadSubscriptionOptionVisibility(View.GONE)
+```
+
+
+
+### The Thread Header Bell
+
+[CometChatThreadHeader](/ui-kit/android/threaded-messages-header) renders a subscription bell as a trailing control on the reply-count bar. It flips optimistically on tap and reverts with a toast if the request fails.
+
+
+
+```kotlin lines
+// Hide the bell (e.g. because you host your own — see below)
+threadHeader.setThreadSubscriptionVisibility(View.GONE)
+
+// Observe state changes (isSubscribed = the new state)
+threadHeader.setOnThreadSubscriptionChange { isSubscribed ->
+ Log.d(TAG, "Thread subscribed: $isSubscribed")
+}
+```
+
+The visibility can also be set in XML with the `app:cometchatThreadSubscriptionVisibility` attribute.
+
+
+
+```kotlin lines
+CometChatThreadHeader(
+ parentMessage = parentMessage,
+ hideThreadSubscription = false, // hide the built-in bell when true
+ isSubscribed = null, // null = seed from parentMessage.isThreadSubscribed()
+ onSubscriptionToggle = { isSubscribed ->
+ Log.d(TAG, "Thread subscribed: $isSubscribed")
+ },
+ threadSubscriptionView = null // or your own composable replacing the bell
+)
+```
+
+
+
+#### Hosting the Bell in Your Own Top Bar
+
+Many apps (matching the CometChat sample apps and Figma) place the subscription bell in the thread screen's **top title bar** rather than the reply-count row. In Compose, the bell is available as a standalone public composable — hide the header's built-in one and host `ThreadSubscriptionBell` wherever you like:
+
+
+
+```kotlin lines
+TopAppBar(
+ title = { Text(stringResource(R.string.thread)) },
+ actions = {
+ ThreadSubscriptionBell(parentMessage = parentMessage)
+ }
+)
+
+CometChatThreadHeader(
+ parentMessage = parentMessage,
+ hideThreadSubscription = true // the bell lives in the top bar instead
+)
+```
+
+
+```kotlin lines
+// Hide the kit header's bell and drive your own ImageView in the activity's title bar:
+threadHeader.setThreadSubscriptionVisibility(View.GONE)
+
+// On tap: flip your icon optimistically, then call the SDK
+CometChat.subscribeToThread(parentMessage.id, object : CometChat.CallbackListener() {
+ override fun onSuccess(response: String?) { }
+ override fun onError(e: CometChatException?) {
+ // revert the icon and show a toast
+ }
+})
+```
+
+
+
+### Subscription Behavior
+
+- **Optimistic with revert** — both surfaces flip instantly on tap, keep one request in flight per thread, and revert with a toast if the server rejects the change. An offline tap fails visibly and reverts; nothing is queued.
+- **Auto-subscribe on reply** — sending a reply in a thread subscribes the user, and every surface flips to the subscribed state automatically.
+- **Unsubscribing is not sticky** — replying again, or being @-mentioned, re-subscribes the user.
+- **Unknown state renders as unsubscribed** — a message whose subscription state hasn't been learned yet (for example, one that just arrived in real time) shows the enabled subscribe control, never a spinner.
+
+### Cross-Surface Sync
+
+Both surfaces observe the UI Kit event bus, so toggling in one place updates the other without a refetch. If you build your own subscription control, emit and collect `CometChatThreadEvent` through `CometChatEvents.threadEvents` — see [Events](/ui-kit/android/events).
+
+### Notifications
+
+Whether a subscribed thread actually produces a push notification is governed by the user's notification preferences: the replies preference supports notifying only for **threads the user is subscribed to** (`SUBSCRIBE_TO_SUBSCRIBED_THREADS`). See [Thread Subscription (SDK)](/sdk/android/v5/thread-subscription#notification-preferences).
+
## Summary / Feature Matrix
| Feature | Component / Method |
@@ -283,12 +391,13 @@ if (user.isBlockedByMe) {
| Show parent message | `header.setParentMessage(parentMessage)` |
| Compose reply | `composer.setParentMessageId(parentMessage.getId())` |
| Handle blocked users | `isBlockedByMe()`, hide composer + show unblock UI |
+| Subscribe / unsubscribe | Action-sheet option + `CometChatThreadHeader` bell |
## Next Steps & Further Reading
-
- Let users subscribe to or unsubscribe from a thread to control whether its replies notify them.
+
+ The underlying APIs, including fetching the threads a user participates in to build a thread inbox.
Explore this feature in the CometChat SampleApp:
diff --git a/ui-kit/android/message-list.mdx b/ui-kit/android/message-list.mdx
index 723f3ad1f..b567a3f08 100644
--- a/ui-kit/android/message-list.mdx
+++ b/ui-kit/android/message-list.mdx
@@ -850,7 +850,7 @@ Available visibility methods (Kotlin XML):
| `setTranslateMessageOptionVisibility()` | `VISIBLE` | Translate message |
| `setShareMessageOptionVisibility()` | `VISIBLE` | Share message |
| `setMarkAsUnreadOptionVisibility()` | `GONE` | Mark as unread |
-| `setThreadSubscriptionOptionVisibility()` | `VISIBLE`* | Subscribe / Unsubscribe thread option (*renders only when the thread-subscription feature gate is on) |
+| `setThreadSubscriptionOptionVisibility()` | `VISIBLE` | Subscribe / Unsubscribe thread option |
### Feature Options (Pin, Save, Thread Subscription)
@@ -858,9 +858,9 @@ Three groups of options appear automatically when their feature is enabled for t
- **Pin message / Unpin message** — shown on text and media messages when `CometChatUIKit.isPinMessageEnabled()`. The option is shown to **every** participant: permission is enforced by the server, and a user who lacks it gets a "you don't have permission" toast (`ERR_PERMISSION_DENIED`) rather than a hidden option. Pinning applies immediately with a toast; unpinning asks for confirmation first. Pinned messages get a pin indicator in the bubble footer.
- **Save message / Unsave message** — shown on text and media messages when `CometChatUIKit.isSaveMessageEnabled()`, for every user. Saving applies immediately with a toast; unsaving asks for confirmation first. Saved messages get a bookmark indicator in the bubble footer.
-- **Subscribe to thread / Unsubscribe from thread** — shown on regular messages (not agent or moderation-blocked ones) when thread subscription is enabled via `UIKitSettings.setEnableThreadSubscription(true)`. On a thread reply the action targets the thread's root message. Hide it with `setThreadSubscriptionOptionVisibility(View.GONE)`.
+- **Subscribe to thread / Unsubscribe from thread** — shown on regular messages (not agent or moderation-blocked ones). On a thread reply the action targets the thread's root message. Hide it with `setThreadSubscriptionOptionVisibility(View.GONE)`.
-Pin and Save are withheld on messages where the action is meaningless or would fail — deleted messages, messages that have not finished sending, and messages held or rejected by moderation. The labels toggle with the message's current state, and if a pin/save limit is exceeded the limit toast is generated from the server response automatically. See the [Pin & Save Messages](/ui-kit/android/guide-pin-and-save-messages) and [Thread Subscription](/ui-kit/android/guide-thread-subscription) guides.
+Pin and Save are withheld on messages where the action is meaningless or would fail — deleted messages, messages that have not finished sending, and messages held or rejected by moderation. The labels toggle with the message's current state, and if a pin/save limit is exceeded the limit toast is generated from the server response automatically. See the [Pin & Save Messages](/ui-kit/android/guide-pin-and-save-messages) guide and [Threaded Messages → Thread Subscription](/ui-kit/android/guide-threaded-messages#thread-subscription).
### Replacing All Options (`setOptions`)
diff --git a/ui-kit/android/methods.mdx b/ui-kit/android/methods.mdx
index 963704528..f8da9c17f 100644
--- a/ui-kit/android/methods.mdx
+++ b/ui-kit/android/methods.mdx
@@ -74,7 +74,6 @@ The `UIKitSettings` is an important parameter of the `init()` function. It serve
| **setAIFeatures** | `List` | Sets the AI Features that need to be added in UI Kit |
| **setExtensions** | `List` | Sets the list of extension that need to be added in UI Kit |
| **dateTimeFormatterCallback** | `DateTimeFormatterCallback` | Interface containing callback methods to format different types of timestamps. |
-| **setEnableThreadSubscription** | `Boolean` | Opt in to the thread subscription feature. Default `false` — no subscription controls render without it. See [Thread Subscription](/ui-kit/android/guide-thread-subscription) |
**Usage:**
@@ -427,7 +426,6 @@ Synchronous, UI-safe checks for whether a feature is available. Use them to gate
| `CometChatUIKit.isPinMessageEnabled()` | Whether the Pin Message feature is enabled for the app. |
| `CometChatUIKit.isSaveMessageEnabled()` | Whether the Save Message feature is enabled for the app. |
| `CometChatUIKit.isPinConversationEnabled()` | Whether the Pin Conversation feature is enabled for the app. |
-| `CometChatUIKit.isThreadSubscriptionEnabled()` | Whether thread subscription was opted into via `UIKitSettings.setEnableThreadSubscription(true)`. |
```kotlin
if (CometChatUIKit.isPinMessageEnabled()) {
diff --git a/ui-kit/android/threaded-messages-header.mdx b/ui-kit/android/threaded-messages-header.mdx
index cc9db9a38..affee6427 100644
--- a/ui-kit/android/threaded-messages-header.mdx
+++ b/ui-kit/android/threaded-messages-header.mdx
@@ -97,7 +97,7 @@ Prerequisites: CometChat SDK initialized with `CometChatUIKit.init()`, a user lo
#### Subscription Bell (`onThreadSubscriptionChange` / `onSubscriptionToggle`)
-When [thread subscription](/ui-kit/android/guide-thread-subscription) is enabled (`UIKitSettings.setEnableThreadSubscription(true)`), the header renders a subscription bell as a trailing control on the reply-count bar. It flips optimistically on tap, reverts with a toast on failure, and stays in sync with the message list's Subscribe/Unsubscribe option automatically.
+The header renders a [thread subscription](/ui-kit/android/guide-threaded-messages#thread-subscription) bell as a trailing control on the reply-count bar. It flips optimistically on tap, reverts with a toast on failure, and stays in sync with the message list's Subscribe/Unsubscribe option automatically.
@@ -155,7 +155,7 @@ The component listens to SDK events internally via its ViewModel. No manual setu
| `setAvatarVisibility(View.GONE)` | `hideAvatar = true` | Toggle avatar visibility |
| `setReceiptsVisibility(View.GONE)` | `hideReceipts = true` | Toggle read receipts |
| `setReplyCountVisibility(View.GONE)` | `hideReplyCount = true` | Toggle reply count text |
-| `setThreadSubscriptionVisibility(View.GONE)` | `hideThreadSubscription = true` | Toggle the subscription bell (renders only when thread subscription is enabled) |
+| `setThreadSubscriptionVisibility(View.GONE)` | `hideThreadSubscription = true` | Toggle the subscription bell |
| `setOnThreadSubscriptionChange { }` | `onSubscriptionToggle = { }` | Subscription-state change callback |
| — | `threadSubscriptionView = { }` | Replace the bell with a custom composable |
diff --git a/ui-kit/react/core-features.mdx b/ui-kit/react/core-features.mdx
index e9d56d92a..afec81f80 100644
--- a/ui-kit/react/core-features.mdx
+++ b/ui-kit/react/core-features.mdx
@@ -152,6 +152,17 @@ The Threaded Conversations feature enables users to respond directly to a specif
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| [Threaded Message Preview](/ui-kit/react/guide-threaded-messages) | [Threaded Message Preview](/ui-kit/react/guide-threaded-messages) component displays the parent message along with the number of replies. |
+### Thread Subscription
+
+Let users subscribe to or unsubscribe from a thread to control whether its replies notify them. Enabled by default — remove a surface with `hideThreadSubscriptionToggle` or `hideThreadSubscriptionOption`.
+
+| Component | Role |
+| --- | --- |
+| [Message List](/ui-kit/react/components/message-list#hidethreadsubscriptionoption) | Provides the Subscribe to thread / Unsubscribe from thread option in the message context menu. |
+| [Thread Header](/ui-kit/react/components/thread-header#thread-subscription) | Shows the subscription bell on the thread view. |
+
+See [Threaded Messages → Thread Subscription](/ui-kit/react/guide-threaded-messages#thread-subscription) for setup and behavior.
+
## Quoted Replies
Quoted Replies is a robust feature provided by CometChat that enables users to quickly reply to specific messages by selecting the "Reply" option from a message's action menu. This enhances context, keeps conversations organized, and improves overall chat experience in both 1-1 and group chats.