> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-v6-beta2-flutter-uikit.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Best Practices

> Recommended patterns and practices for building with the CometChat JavaScript SDK.

Follow these best practices to build reliable, performant, and secure applications with the CometChat JavaScript SDK. Organized by topic — jump to what's relevant for your current work.

## Initialization & Authentication

| Practice                      | Description                                                                                                                                                                       |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Initialize once at startup    | Call `CometChat.init()` in your entry file (`index.js`, `main.js`, or `App.js`). It only needs to be called once per session.                                                     |
| Use environment variables     | Store App ID, Region, and Auth Key in environment variables rather than hardcoding them.                                                                                          |
| Check for existing sessions   | Before calling `login()`, use `CometChat.getLoggedinUser()` to check if a session already exists.                                                                                 |
| Use Auth Tokens in production | Auth Keys are for development only. Generate Auth Tokens server-side using the [REST API](https://api-explorer.cometchat.com/reference/create-authtoken).                         |
| Handle token expiry           | Implement a mechanism to detect login failures due to expired tokens. Use the [Login Listener](/sdk/javascript/authentication-overview#login-listener) to detect session changes. |
| Logout on sign-out            | Always call `CometChat.logout()` when your user signs out to clear the SDK session and stop real-time events.                                                                     |

## Listeners

| Practice                          | Description                                                                                                     |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Use unique listener IDs           | Use descriptive IDs like `"MESSAGE_LISTENER_CHAT_SCREEN"` to avoid accidental overwrites.                       |
| Register early, remove on cleanup | Register listeners after `login()`. Remove them when the component is destroyed to prevent memory leaks.        |
| Keep callbacks lightweight        | Avoid heavy processing inside listener callbacks. Dispatch events to your state management layer.               |
| Use specific listeners            | Only register the listener types you need. Don't register a `GroupListener` if your page only handles messages. |

## Pagination & Caching

| Practice                       | Description                                                                                                 |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Use reasonable limits          | Set `setLimit()` to 30-50 for users, messages, and group members.                                           |
| Reuse request objects          | Call `fetchNext()`/`fetchPrevious()` on the same request instance. Creating a new object resets the cursor. |
| Cache frequently accessed data | Store user and group objects locally to reduce API calls.                                                   |

## Rate Limits

| Practice                    | Description                                                                                                                                    |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Batch operations            | Space out bulk operations using a queue or throttle mechanism.                                                                                 |
| Monitor rate limit headers  | Check `X-Rate-Limit-Remaining` in REST API responses to slow down before hitting limits.                                                       |
| Distinguish operation types | Core operations (login, create/delete user) share a 10,000/min limit. Standard operations have 20,000/min. Avoid frequent login/logout cycles. |

## SSR Frameworks

| Practice                    | Description                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------- |
| Initialize client-side only | CometChat requires browser APIs. Use dynamic imports or `useEffect` for Next.js, Nuxt, etc. |
| Use loading states          | Show a loading indicator while the SDK initializes to prevent hydration mismatches.         |

## Messaging

| Practice                      | Description                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------------------------- |
| Use appropriate message types | Choose text, media, or custom messages based on your content.                               |
| Add metadata for context      | Use `setMetadata()` to attach location, device info, or other contextual data.              |
| Handle errors gracefully      | Always implement error callbacks to handle network issues or invalid parameters.            |
| Validate file types           | Before sending media messages, verify the file type matches the message type.               |
| Hide deleted/blocked content  | Use `hideDeletedMessages(true)` and `hideMessagesFromBlockedUsers(true)` for cleaner lists. |

## Threaded Messages

| Practice               | Description                                                                   |
| ---------------------- | ----------------------------------------------------------------------------- |
| Track active thread ID | Store the current thread's `parentMessageId` to filter incoming messages.     |
| Use hideReplies(true)  | Exclude thread replies from main conversation to avoid clutter.               |
| Show reply count       | Display the number of replies on parent messages to indicate thread activity. |

## Reactions & Mentions

| Practice                   | Description                                                  |
| -------------------------- | ------------------------------------------------------------ |
| Update UI optimistically   | Show reactions immediately, then sync with server response.  |
| Use correct mention format | Always use `<@uid:UID>` format for mentions in message text. |
| Highlight mentions in UI   | Parse message text and style mentions differently.           |

## Typing Indicators

| Practice               | Description                                                                          |
| ---------------------- | ------------------------------------------------------------------------------------ |
| Debounce typing events | Don't call `startTyping()` on every keystroke - debounce to \~300ms intervals.       |
| Auto-stop typing       | Call `endTyping()` after 3-5 seconds of inactivity or when the user sends a message. |

## Delivery & Read Receipts

| Practice                   | Description                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------- |
| Mark as delivered on fetch | Call `markAsDelivered()` when messages are fetched and displayed.                  |
| Mark as read on view       | Call `markAsRead()` when the user actually views/scrolls to a message.             |
| Batch receipts             | Mark the last message in a batch - all previous messages are automatically marked. |

## Groups

| Practice                          | Description                                                                                |
| --------------------------------- | ------------------------------------------------------------------------------------------ |
| Use meaningful GUIDs              | Choose descriptive, unique GUIDs (e.g., `"project-alpha-team"`).                           |
| Set group type carefully          | Group type cannot be changed after creation. Choose between PUBLIC, PASSWORD, and PRIVATE. |
| Add members at creation           | Use `createGroupWithMembers()` to add initial members in a single API call.                |
| Check hasJoined before joining    | Avoid unnecessary API calls by checking the group's `hasJoined` property first.            |
| Transfer ownership before leaving | Owners must transfer ownership to another member before they can leave.                    |
| Use joinedOnly(true)              | Filter to joined groups when building sidebars or group lists.                             |

## Group Members

| Practice                | Description                                                                      |
| ----------------------- | -------------------------------------------------------------------------------- |
| Batch member additions  | Add multiple members in a single `addMembersToGroup()` call.                     |
| Set appropriate scopes  | Assign `PARTICIPANT` by default. Only use `ADMIN` or `MODERATOR` when needed.    |
| Handle partial failures | Check each entry in the response array for `"success"` or an error message.      |
| Use scope constants     | Use `CometChat.GROUP_MEMBER_SCOPE.ADMIN` instead of raw strings.                 |
| Kick vs. Ban            | Use kick when the user can rejoin. Use ban for permanent removal until unbanned. |

## Calling

| Practice                            | Description                                                                                             |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Initialize Calls SDK after Chat SDK | Always initialize Chat SDK (`CometChat.init()`) before Calls SDK (`CometChatCalls.init()`).             |
| Store session ID immediately        | Save the session ID from `initiateCall()` response - you'll need it for accept, reject, cancel.         |
| Handle all call states              | Implement handlers for all listener events (accepted, rejected, cancelled, busy, ended).                |
| Generate tokens just-in-time        | Generate call tokens immediately before starting a session rather than caching them.                    |
| Clean up on session end             | Always call `CometChatCalls.endSession()` in both `onCallEnded` and `onCallEndButtonPressed` callbacks. |
| Inform users about recording        | Always notify participants when recording starts - this is often a legal requirement.                   |

## Custom CSS (Calling)

| Practice                        | Description                                                                 |
| ------------------------------- | --------------------------------------------------------------------------- |
| Only use documented CSS classes | Undocumented internal classes may break with SDK updates.                   |
| Don't resize the grid container | Only customize colors, borders, and visibility.                             |
| Test across modes               | CSS changes may look different in `DEFAULT`, `TILE`, and `SPOTLIGHT` modes. |
| Keep button sizes accessible    | Minimum 44x44px for touch targets.                                          |

## Connection & WebSocket

| Practice                           | Description                                                                               |
| ---------------------------------- | ----------------------------------------------------------------------------------------- |
| Register connection listener early | Add the listener right after `CometChat.init()` succeeds.                                 |
| Show connection status in UI       | Display a banner when disconnected so users know messages may be delayed.                 |
| Queue actions during disconnection | Queue user actions and retry once `onConnected` fires.                                    |
| Don't poll getConnectionStatus()   | Use the listener-based approach instead.                                                  |
| Reconnect on app foreground        | If you disconnect in background, call `CometChat.connect()` when returning to foreground. |

## AI Features

| Practice                               | Description                                                                                  |
| -------------------------------------- | -------------------------------------------------------------------------------------------- |
| Register both listeners for AI Agents  | Use `AIAssistantListener` for streaming events and `MessageListener` for persisted messages. |
| Handle streaming progressively         | Render the assistant's reply token-by-token using `Text Message Content` events.             |
| Show pending state for moderation      | Display a visual indicator when `getModerationStatus()` returns `PENDING`.                   |
| Handle disapproved messages gracefully | Show a placeholder or notification so the sender understands what happened.                  |
| Track pending messages                 | Maintain a local map of pending message IDs to update UI when moderation results arrive.     |

## Upgrading from V3

| Practice                     | Description                                                                                           |
| ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| Follow the setup guide first | Complete the v4 [setup instructions](/sdk/javascript/setup-sdk) before changing imports.              |
| Update all imports at once   | Use find-and-replace to change all `@cometchat-pro/chat` imports to `@cometchat/chat-sdk-javascript`. |
| Test incrementally           | Test each feature area (messaging, calling, groups) individually after updating.                      |
| Remove old packages          | Uninstall v3 packages (`npm uninstall @cometchat-pro/chat`) to avoid conflicts.                       |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Troubleshooting" icon="wrench" href="/sdk/javascript/troubleshooting">
    Common issues and solutions
  </Card>

  <Card title="Error Codes" icon="triangle-exclamation" href="/sdk/javascript/error-codes">
    Complete SDK error code reference
  </Card>

  <Card title="Rate Limits" icon="gauge-high" href="/sdk/javascript/rate-limits">
    Understand and handle API rate limits
  </Card>

  <Card title="Setup SDK" icon="gear" href="/sdk/javascript/setup-sdk">
    Installation and initialization guide
  </Card>
</CardGroup>
