docs(react,sdk/javascript): align thread subscription and pin/save with other platforms - #518
Conversation
…th other platforms Bring the React UI Kit and JavaScript SDK docs onto the same page as Android, Angular and iOS for thread subscription, pin & save, and pin conversations. React UI Kit: - core-features: add Thread Subscription as a subsection of Threaded Conversations, which previously carried no mention of the feature. Unlike Android and Angular, React has no enable flag, so the section says so explicitly rather than inheriting their "off by default" framing. - core-features: split Pin Conversations into its own section instead of bundling it as a row of the Pin & Save table, matching Android. - core-features and the pin/save guide: pair the .enabled keys with the .limit keys, so each section documents both halves of its app settings. - core-features: add Message Bubble and Message Header to the Pin & Save component table; both behaviours were already documented in the guide but missing from the table. - Retitle the guide's Limits step to App Settings and Limits, and repoint the conversation-pin links at the Pin Conversation anchor. JavaScript SDK: - thread-subscription: add Notification Preferences, covering RepliesOptions.SUBSCRIBE_TO_SUBSCRIBED_THREADS, and cross-link the QuotedRepliesOptions content in notifications/preferences. Flag that the two enums are distinct so the raw value 4 is not read as interchangeable. - pin-message, save-message, pin-conversation: add Error Handling. Only ERR_ACTION_NOT_ALLOWED was named anywhere across these pages, leaving nothing to branch on in a catch block; the limit-exceeded codes were invisible despite the Pin Limit section advising callers to pre-empt the cap. Codes are read off the kit's own handling, and the sections point at the limit getters as the source for the cap rather than the error text. System pin limit keys are deliberately left out of the UI Kit docs: the kit reads isSystemPinned() for ordering and for suppressing unpin, never the features.ux.*.system.limit settings, and a user cannot system-pin from the UI. They stay documented on the SDK side, where they are reachable. Docs only; no UI Kit or SDK source changes.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
raj-dubey1
left a comment
There was a problem hiding this comment.
Review: changes requested on the SDK error-handling tables
The structure is clean and the React UI Kit half is accurate. The new Error Handling tables in the JS SDK pages are there so readers can branch on codes, but several rows give the wrong meaning, and pin-message.mdx now contradicts itself. I checked each code against the chat-api server source (master, 2026-09-01), JS SDK 4.2.0, and React UI Kit 7.2.0.
Must fix
1. sdk/javascript/pin-message.mdx gives two different codes for a member's pin
- The intro note at L9-11 says a member's pin is rejected with
ERR_ACTION_NOT_ALLOWED. - The new table at L248-249 says role refusal is
ERR_PERMISSION_DENIED. - The server returns
ERR_PERMISSION_DENIEDfor a role/scope refusal, so the table is right and the intro is stale. Please update L9-11 in this PR so the page says one thing. (The SDK's own JSDoc forpinMessagehas the same staleERR_ACTION_NOT_ALLOWEDclaim, which is probably where it came from.)
2. "ERR_ACTION_NOT_ALLOWED = feature not enabled" is wrong in all three tables (pin-message.mdx L249, pin-conversation.mdx L243, save-message.mdx L256)
- When the feature is off, the pin, unpin, save, unsave and conversation pin/unpin endpoints return
ERR_FEATURE_NOT_ACCESSIBLE(HTTP 403, "…feature is not available. To enable this feature, please upgrade your plan."). - The server never returns
ERR_ACTION_NOT_ALLOWEDfor these calls. The SDK declares it as a constant but never throws it, so a catch block built from this table will never catch the feature-off case. - The kit doesn't give the two codes separate meanings: it treats
ERR_ACTION_NOT_ALLOWEDandERR_PERMISSION_DENIEDas one "permission" group. If you keepERR_ACTION_NOT_ALLOWED, describe it as a permission refusal next toERR_PERMISSION_DENIED, not as feature-off.
3. sdk/javascript/pin-conversation.mdx lists a code this endpoint can't return, and misses the real one
- L244
ERR_PERMISSION_DENIED: conversation pin/unpin has no role or permission check, so this endpoint never returns it. - Pinning or unpinning a system-pinned conversation returns
ERR_SYSTEM_PINNED_CONVERSATION. L246 mentions system pins without naming the code, and the older L87 says it'sERR_ACTION_NOT_ALLOWED. Please nameERR_SYSTEM_PINNED_CONVERSATIONin the table and fix L87.
Nits
- "The code arrives either top-level or nested, so read it defensively" (
pin-message.mdxL253,pin-conversation.mdxL248,save-message.mdxL261). This isn't true for the SDK: every pin/save rejection is wrapped in aCometChatException, soerror.codeis always top-level, as the sentence above it says. The(error as any)?.error?.codepattern comes from the kit's internal helper. It's also TypeScript-only, while the rest of these pages use TS/JS<Tabs>. Plainerror.codein Tabs would match the existing Error Handling section inthread-subscription.mdx. - The code lists are incomplete. The server also returns:
ERR_MESSAGE_ID_NOT_FOUNDfor a deleted or unknown message.ERR_MESSAGE_ACTION_NOT_ALLOWEDwhen pinning a message that moderation rejected (ERR_MESSAGE_NO_ACCESScovers only pending moderation and non-participants).ERR_CONVERSATION_NOT_FOUNDfor conversation pin/unpin.
save-message.mdxL259: "a user may always save any message they can see" contradicts the row above it. A sender can see their own pending-moderation message, but saving it fails withERR_MESSAGE_NO_ACCESS, and the save cap also applies. Something like "no role gate: any participant can save a message they have access to, up to the cap."- The limit notes (
pin-message.mdxL260,pin-conversation.mdxL255,save-message.mdxL268) say the getter "returns the configured value directly". The getters returnPromise<number | null>, so "resolves to the configured cap, ornullwhen unset" matches the section right above. thread-subscription.mdxL322: the snippet buildsGroupPreferencesbut never callssetGroupPreferences()orCometChatNotifications.updatePreferences(), so copying it changes nothing. It also covers groups only, though threads work in 1:1 too (OneOnOnePreferences.setRepliesPreferenceexists). It's a single TS block, while the rest of the page uses TS/JS Tabs.ui-kit/react/core-features.mdxL172: "The UI Kit also subscribes a user automatically…". The server does the auto-subscribe (it covers the replier, mentioned members, and the thread starter unless they unfollowed), so SDK-only apps get it too. The wording comes from the existing threaded-messages guide, so fixing both is optional.ui-kit/react/core-features.mdxL214: "a cap on how many items a user may pin" doesn't hold for pinned messages, which are capped per conversation (the row right below says so).
What checked out
- Structure: no files moved or deleted, so no redirects are needed. There are 0 broken
docs.jsonpage references, so the build is safe. - Links: 0 broken internal links in the changed files. All 28
#anchorlinks resolve, including the renamed#step-5-app-settings-and-limits, and nothing still links to the old#step-5-limits. - "No enable flag" for React thread subscription is correct. The kit has only the
hide*props anduseThreadSubscription, and the server has no flag. - The "raw
4" warning is correct. At runtimeRepliesOptions.SUBSCRIBE_TO_SUBSCRIBED_THREADSandQuotedRepliesOptions.SUBSCRIBE_TO_QUOTES_ON_OWN_MESSAGESare both4, and this matchesnotifications/preferences.mdx. - The new React rows are accurate: the Message Header "Pinned messages" entry, the
features.ux.*.enabled/.limitkeys, and the limit getter signatures.
Already broken on main, not from this PR: /sdk/javascript/default-call and /sdk/javascript/direct-call (in message-structure-and-hierarchy.mdx), and /sdk/javascript/interactive-messages (in send-message.mdx).
These codes come from reading the server source, not from live calls. A quick live check of the feature-off and system-pin cases would be worth doing if the deployed server differs.
…live server Addresses review feedback on #518. The error-handling tables added in the previous commit were written from the SDK's JSDoc and constants; several rows were wrong. Every code below was verified by calling the endpoints against the e2e app and recording what came back, rather than by reading source. Corrected: - pin-message: a member's pin is rejected with ERR_PERMISSION_DENIED (HTTP 403), not ERR_ACTION_NOT_ALLOWED. The page previously said both, in two places. The stale claim came from the SDK JSDoc on pinMessage and from PIN_SAVE_ERROR_CODES, which both name ERR_ACTION_NOT_ALLOWED as the SBAC rejection; those are wrong at source and need a separate fix. - Drop "ERR_ACTION_NOT_ALLOWED means the feature is not enabled" from all three tables. Nothing supports it, and the server was never observed returning it. - pin-conversation: drop the speculative ERR_PERMISSION_DENIED row. Conversation pinning is per-user with no role gate. A missing peer returns ERR_UID_NOT_FOUND or ERR_GUID_NOT_FOUND (HTTP 404). Added, each observed: - ERR_MESSAGE_ID_NOT_FOUND (404) on pin and save. - ERR_MESSAGE_NO_ACCESS (403) when the caller is not a participant. - HTTP status alongside every row, including the limit codes (ERR_PINNED_MESSAGES_LIMIT_EXCEEDED, 400, message carrying "limit of N"). - Unpinning a conversation that was never pinned succeeds rather than erroring. Also from the review: - Use plain error.code in TypeScript/JavaScript tabs instead of a defensive top-level-or-nested read. The SDK unwraps the REST shape before rejecting, so the code is always top-level; the nested pattern belongs to the UI Kit's own helper, not to this API. - The limit getters resolve to the configured cap or null, so say that rather than "returns the configured value directly". - thread-subscription: the preferences example now calls updatePreferences() — without it the snippet changed nothing — and sets one-on-one alongside group, since threads are not group-only. - core-features and the threaded-messages guide: auto-subscribe is performed by the server, so it applies to any app on the SDK. The kit only reflects it. - core-features: pinned messages are capped per conversation, not per user. - save-message: a participant can save a message they have access to, up to the cap, which no longer contradicts the ERR_MESSAGE_NO_ACCESS row above it. Two cases stay as they were, both unverifiable from here: whether unpinning a system-pinned conversation returns ERR_SYSTEM_PINNED_CONVERSATION (system pins cannot be created through the admin API, which requires onBehalfOf and so makes an ordinary user pin), and which code a disabled feature returns (needs an app-settings toggle on the shared e2e app). Both keep the SDK's current wording rather than adopting an unconfirmed code. Docs only; no UI Kit or SDK source changes.
Description
Bring the React UI Kit and JavaScript SDK docs onto the same page as Android, Angular and iOS for thread subscription, pin & save, and pin conversations.
React UI Kit:
JavaScript SDK:
System pin limit keys are deliberately left out of the UI Kit docs: the kit reads isSystemPinned() for ordering and for suppressing unpin, never the features.ux.*.system.limit settings, and a user cannot system-pin from the UI. They stay documented on the SDK side, where they are reachable.
Docs only; no UI Kit or SDK source changes.
Related Issue(s)
Type of Change
Checklist
Additional Information
Screenshots (if applicable)