# Configuration tree

> **Info:** This is release candidate documentation for **Stream Chat React SDK v15**. For the latest stable version, see the [latest version (v14)](https://getstream.io/chat/docs/sdk/react/).

This page lists every setting `client.config` takes, key by key, with its type and default. It follows `INSTANCE_CONFIG_TREE_SHAPE` in `stream-chat`, which describes the same tree at runtime.

How to set these, the order in which they combine, and what the server decides are explained on [Configuration](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/configuration/). The same tree goes to `client.config.set()`, to `new StreamChat(apiKey, tree)` and to `StreamChat.getInstance(apiKey, tree)`:

```ts
client.config.set({
  channel: { typingEvents: { enabled: false } },
  messageComposer: { drafts: { enabled: true } },
});
```

Two marks appear in the tables:

- **Server:** the channel type's setting named after the mark can narrow the value. A switch is on only when the client and the server both allow it, and a server limit lowers a larger client limit. The value in effect is in `channel.config` or `composer.config`.
- **Read once:** the value is read only when the object is built. Set it before the objects exist: pass it to the `StreamChat` constructor, or set it next to `StreamChat.getInstance()`. Set later, it doesn't reach the objects that exist already, and the client logs a warning.

A `function` value can go in `client.config.set()` like any other value, or be set in a setup function. To list the tree at runtime, for a settings screen for example, read `INSTANCE_CONFIG_TREE_SHAPE` or call `flattenConfigShape()`, which returns every path with its description. Neither holds the defaults.

## channel

Every channel. Setup function: `client.config.setSetupFunction("channel", ({ channel }) => ...)`.

| Key                                  | Type                | Default | What it does                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------ | ------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `typingEvents.enabled`               | `boolean`           | `true`  | Sends typing events from the channel. `messageComposer.text.publishTypingEvents` can turn them off for some composers. **Server:** `typing_events`.                                                                                                                                                                                                              |
| `readEvents.enabled`                 | `boolean`           | `true`  | Allows marking the channel read and unread. Off, `Channel.markRead()` and `Channel.markUnread()` throw. **Server:** `read_events`.                                                                                                                                                                                                                               |
| `readEvents.localUnreadCountEnabled` | `boolean`           | `false` | While `readEvents.enabled` is off, counts unread messages on the device, and `Channel.markReadLocally()` resets the count. The server has no say in it.                                                                                                                                                                                                          |
| `replies.enabled`                    | `boolean`           | `true`  | Offers threaded replies. **Server:** `replies`.                                                                                                                                                                                                                                                                                                                  |
| `userMessageReminders.enabled`       | `boolean`           | `true`  | Offers reminders and save for later. **Server:** `user_message_reminders`.                                                                                                                                                                                                                                                                                       |
| `deliveryEvents.enabled`             | `boolean`           | `true`  | Reports when messages are delivered to the user. **Server:** `delivery_events`.                                                                                                                                                                                                                                                                                  |
| `requestHandlers`                    | object of functions | none    | Handlers that replace the requests for sending, retrying, editing, deleting and marking read: `sendMessageRequest`, `retrySendMessageRequest`, `updateMessageRequest`, `deleteMessageRequest` and `markReadRequest`. Thread replies use these too. See [Request handlers](https://getstream.io/chat/docs/sdk/react/v15/state/writing-messages/message-operations/#request-handlers). |
| `messagePaginator`                   | group               |         | The channel's message list. Takes the fields of [`messagePaginator`](#messagepaginator) and overrides that key, field by field. `pageSize` defaults to 100. **Read once:** `initialCursor`, `initialOffset`, `unreadReferencePolicy`.                                                                                                                            |
| `pinnedMessagesPaginator`            | group               |         | The channel's pinned messages. Takes the fields of [`messagePaginator`](#messagepaginator) except `maxLoadedItems` and `unreadReferencePolicy`. `pageSize` defaults to 100, and `stateThrottleMs` is unset, so updates publish at once. **Read once:** `initialCursor`, `initialOffset`.                                                                         |
| `messageOperations`                  | group               |         | Sending and retrying in channels. Takes the fields of [`messageOperations`](#messageoperations) and overrides that key, field by field.                                                                                                                                                                                                                          |

The list of slash commands a channel offers isn't here. The server sends it, and it's in `channel.config.availableCommands`.

## thread

Every thread. Setup function: `client.config.setSetupFunction("thread", ({ thread }) => ...)`.

| Key                               | Type     | Default | What it does                                                                                                                                                                                                                      |
| --------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `messagePaginator`                | group    |         | The thread's reply list. Takes the fields of [`messagePaginator`](#messagepaginator) and overrides that key, field by field. `pageSize` defaults to 50. **Read once:** `initialCursor`, `initialOffset`, `unreadReferencePolicy`. |
| `messageOperations`               | group    |         | Sending and retrying thread replies. Takes the fields of [`messageOperations`](#messageoperations) and overrides that key, field by field.                                                                                        |
| `requestHandlers.markReadRequest` | function | none    | Replaces the request that marks a thread read. It receives `{ thread, options }`. Sending, editing and deleting replies go through `channel.requestHandlers`.                                                                     |

## messagePaginator

Every message list: a channel's and a thread's alike. `channel.messagePaginator` and `thread.messagePaginator` override it field by field. It has no setup function.

The defaults are those of the lists themselves, since this key has none of its own.

| Key                              | Type                                | Default                          | What it does                                                                                                                                                                                                                              |
| -------------------------------- | ----------------------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pageSize`                       | `number`                            | 100 in a channel, 50 in a thread | Messages per page.                                                                                                                                                                                                                        |
| `debounceMs`                     | `number`                            | `300`                            | Wait before a queued page request goes out, so fast scrolling sends one query.                                                                                                                                                            |
| `stateThrottleMs`                | `number`                            | `500`                            | Shortest gap between two publishes of the list, so a burst of events causes a couple of updates instead of one per event. The user's own sends publish at once.                                                                           |
| `maxLoadedItems`                 | `number`                            | none                             | Caps how many messages stay loaded. Past it, the oldest messages of the latest interval are dropped as new ones arrive, and scrolling back loads them again. A value below `pageSize` is raised to it. Unsent messages are never dropped. |
| `retryCount`                     | `number`                            | `0`                              | Retries of a failed page request before the error lands in `lastQueryError`.                                                                                                                                                              |
| `throwErrors`                    | `boolean`                           | `false`                          | Rethrows a failed page request instead of only recording it in the state.                                                                                                                                                                 |
| `lockItemOrder`                  | `boolean`                           | `false`                          | Keeps loaded messages where they are instead of re-sorting them when one is updated.                                                                                                                                                      |
| `hasPaginationQueryShapeChanged` | `function`                          | the SDK's comparison             | Decides whether a new query differs enough from the last one to drop the loaded pages instead of adding to them.                                                                                                                          |
| `unreadReferencePolicy`          | `'snapshot'` or `'read-state-only'` | `'snapshot'`                     | Where `MessagePaginator.jumpToTheFirstUnreadMessage()` finds the first unread message: in the unread snapshot taken when the channel opened, or in the channel's current read state. **Read once.**                                       |
| `initialCursor`                  | object                              | the latest messages              | The cursor the first page is loaded from. **Read once.**                                                                                                                                                                                  |
| `initialOffset`                  | `number`                            | none                             | The offset the first page is loaded from. **Read once.**                                                                                                                                                                                  |

[Message paginators](https://getstream.io/chat/docs/sdk/react/v15/state/loading-data/message-paginators/) explains throttling, the memory cap and the unread snapshot.

## messageOperations

The cache of failed sends, for every channel and thread. `channel.messageOperations` and `thread.messageOperations` override it field by field. It has no setup function.

| Key                      | Type     | Default              | What it does                                                 |
| ------------------------ | -------- | -------------------- | ------------------------------------------------------------ |
| `failedSendCacheMaxSize` | `number` | `100`                | Failed sends kept for retry. Past it, the oldest is dropped. |
| `failedSendCacheTtlMs`   | `number` | `300000` (5 minutes) | How long a failed send can be retried.                       |

## messageComposer

Every composer: a channel's, a thread's and the ones built to edit a message. Setup function: `client.config.setSetupFunction("messageComposer", ({ composer }) => ...)`. [Message composer](https://getstream.io/chat/docs/sdk/react/v15/state/writing-messages/message-composer/) explains what each part does.

| Key                                      | Type       | Default                              | What it does                                                                                                                                                  |
| ---------------------------------------- | ---------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `attachments.enabled`                    | `boolean`  | `true`                               | Offers file attachments. **Server:** `uploads`, unless `attachments.customCdn` is `true`.                                                                     |
| `attachments.acceptedFiles`              | `string[]` | `[]`                                 | File types for a file picker to offer, as extensions or MIME types. Empty means any. The composer doesn't check it.                                           |
| `attachments.customCdn`                  | `boolean`  | `false`                              | Says that `doUploadRequest` stores files outside Stream. Then the `uploads` setting and the `upload-file` capability don't apply.                             |
| `attachments.doUploadRequest`            | `function` | none: uploads to Stream              | Replaces the upload request. It receives the file and `{ onProgress, abortSignal }`, and resolves with `{ file: url }`.                                       |
| `attachments.fileUploadFilter`           | `function` | accepts every file                   | Rejects files before they upload.                                                                                                                             |
| `attachments.maxNumberOfFilesPerMessage` | `number`   | `10`                                 | Attachments allowed on one message.                                                                                                                           |
| `attachments.pendingUploadsEnabled`      | `boolean`  | `false`                              | Lets a message be sent while its uploads run. The message shows at once, and its request waits for the uploads. One failed upload fails the message.          |
| `attachments.trackUploadProgress`        | `boolean`  | `true`                               | Reports upload progress in each attachment's `localMetadata.uploadProgress`.                                                                                  |
| `commands.sendValidator`                 | `function` | `defaultCommandSendabilityValidator` | Decides whether a message with a slash command can be sent. The default needs a mention for `/ban`, `/mute`, `/unmute` and `/unban`, and a reason for `/ban`. |
| `drafts.enabled`                         | `boolean`  | `false`                              | Saves unsent content as a draft on the server.                                                                                                                |
| `linkPreviews.enabled`                   | `boolean`  | `true`                               | Loads previews for the links in the text. **Server:** `url_enrichment`.                                                                                       |
| `linkPreviews.debounceURLEnrichmentMs`   | `number`   | `1500`                               | Wait after typing stops before previews load. Read when the composer is built, without a warning.                                                             |
| `linkPreviews.findURLFn`                 | `function` | finds URLs with `linkifyjs`          | Finds the URLs in the text that get a preview.                                                                                                                |
| `linkPreviews.onLinkPreviewDismissed`    | `function` | none                                 | Runs when a preview is dismissed.                                                                                                                             |
| `location.enabled`                       | `boolean`  | `true`                               | Offers location sharing. **Server:** `shared_locations`.                                                                                                      |
| `location.getDeviceId`                   | `function` | a new random id for each composer    | Supplies a stable id for the device that shares the location. Read when the composer is built, without a warning.                                             |
| `location.minShareDurationMs`            | `number`   | `60000` (1 minute)                   | Shortest live-location duration that's valid. A shorter one makes the location invalid.                                                                       |
| `polls.enabled`                          | `boolean`  | `true`                               | Offers polls. **Server:** `polls`.                                                                                                                            |
| `retainCompositionOnSubmit`              | `function` | keeps the content of a poll message  | Receives the composer and decides whether sending keeps its content instead of clearing it.                                                                   |
| `text.enabled`                           | `boolean`  | `true`                               | Accepts text input. Off, text changes and selection changes are ignored.                                                                                      |
| `text.defaultValue`                      | `string`   | none                                 | Text the composer starts with.                                                                                                                                |
| `text.maxLengthOnEdit`                   | `number`   | none                                 | Longest text while the user types. Longer input is cut. **Server:** `max_message_length` caps it, and applies when this is unset.                             |
| `text.maxLengthOnSend`                   | `number`   | none                                 | Longest text that can be sent. A longer message isn't sent. **Server:** `max_message_length` caps it, and applies when this is unset.                         |
| `text.publishTypingEvents`               | `boolean`  | `true`                               | Sends typing events as the user types, in every kind of composer. `channel.typingEvents.enabled` must also allow them.                                        |

## client

The client and the managers it owns: the connection, recovery, delivery reports, notifications, reminders and the thread list. Setup function: `client.config.setSetupFunction("client", ({ client }) => ...)`.

| Key                                                 | Type                  | Default                                   | What it does                                                                                                                                                        |
| --------------------------------------------------- | --------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `axiosRequestConfig`                                | object                | a 3000 ms `timeout`                       | Axios settings for the client's requests, such as `timeout`, `headers` and `httpsAgent`. `headers` and `params` are also read on every request. **Read once.**      |
| `baseURL`                                           | `string`              | `https://chat.stream-io-api.com`          | The API's base URL. **Read once.**                                                                                                                                  |
| `notificationManager`                               | `NotificationManager` | the client's own                          | A notification manager to use instead of building one, for example to share one between clients. **Read once.**                                                     |
| `browser`                                           | `boolean`             | detected from `window`                    | Forces browser mode (`true`) or Node mode (`false`).                                                                                                                |
| `allowServerSideConnect`                            | `boolean`             | `false`                                   | Silences the warning `client.connectUser()` logs when it runs on a server, where a connection counts towards your usage.                                            |
| `persistUserOnConnectionFailure`                    | `boolean`             | `false`                                   | Keeps `client.user` when `client.connectUser()` fails, so an app working offline doesn't have to connect again to retry.                                            |
| `connectionRecovery.enabled`                        | `boolean`             | `true`                                    | Brings lists, channels and threads up to date after a reconnect. See [Connection](https://getstream.io/chat/docs/sdk/react/v15/state/connection/).                                      |
| `messageDelivery.markAsDeliveredBufferTimeoutMs`    | `number`              | `1000`                                    | How long delivery reports collect before they're sent together.                                                                                                     |
| `messageDelivery.markAsReadThrottleTimeoutMs`       | `number`              | `1000`                                    | Shortest gap between two automatic mark-read requests.                                                                                                              |
| `messageDelivery.maxDeliveredMessageCountInPayload` | `number`              | `100`                                     | Delivery reports in one request. The rest go in the next one.                                                                                                       |
| `messageDelivery.retryCountLimitForTimeoutIncrease` | `number`              | `3`                                       | Timeouts in a row before the wait between delivery reports grows.                                                                                                   |
| `networkConnection.statusReporter`                  | `function`            | the browser's reporter, in a browser      | Reports the device's network status. Outside a browser, a stand-in follows the WebSocket until you supply one, which React Native apps should do.                   |
| `notifications.durations`                           | object                | `3000` for each severity                  | How long a notification stays, in milliseconds, per severity: `error`, `warning`, `info` and `success`.                                                             |
| `notifications.sortComparator`                      | `function`            | none                                      | Orders the notifications shown at the same time.                                                                                                                    |
| `reminders.scheduledOffsetsMs`                      | `number[]`            | 2 and 30 minutes, 1, 2 and 8 hours, 1 day | The "remind me in…" choices, as offsets from now in milliseconds. See [Reminder manager](https://getstream.io/chat/docs/sdk/react/v15/reference/state/reminder-manager/#configuration). |
| `reminders.stopTimerRefreshBoundaryMs`              | `number`              | 2 weeks                                   | How long after its deadline a reminder's timer keeps refreshing its time left.                                                                                      |
| `threads.connectionRecoveryThrottleMs`              | `number`              | `1000`                                    | Shortest gap between two reloads of the thread list after reconnects. A change applies the next time the thread manager starts its subscriptions.                   |
| `wsConnection.connectTimeoutMs`                     | `number`              | `15000`                                   | How long connecting waits for the server's answer.                                                                                                                  |
| `wsConnection.pingIntervalMs`                       | `number`              | `25000`                                   | How often a health-check ping goes out. Held between 1000 and 25000, so it can only make pings more frequent.                                                       |
| `wsConnection.healthCheckGracePeriodMs`             | `number`              | `10000`                                   | Time on top of the ping interval before the socket counts as dead. At least 1000.                                                                                   |
| `wsConnection.offlineNotificationDisplayDelayMs`    | `number`              | `5000`                                    | How long a connection drop must last before a UI reports it. The client itself doesn't wait on it.                                                                  |
| `wsConnection.enableWSFallback`                     | `boolean`             | `false`                                   | Falls back to HTTP long-polling when the WebSocket can't connect, and stays on it.                                                                                  |
| `wsConnection.urlParams`                            | `URLSearchParams`     | none                                      | Extra query parameters on the WebSocket URL.                                                                                                                        |
| `wsConnection.webSocketImpl`                        | `function`            | the global `WebSocket`                    | The `WebSocket` constructor to use, for hosts without one.                                                                                                          |
| `wsConnection.connection`                           | object                | none                                      | A pre-built connection to use instead of opening one. Meant for tests.                                                                                              |

## liveLocationManager

Live location sharing. A `LiveLocationManager` is created by the UI layer or by your app, never by the client, and it reads this key itself. Setup function: `client.config.setSetupFunction("liveLocationManager", ({ liveLocationManager }) => ...)`.

| Key                   | Type     | Default | What it does                                                                                               |
| --------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `minUpdateThrottleMs` | `number` | `3000`  | Shortest gap between two live-location update requests. Raising it is safe; lowering it risks rate limits. |

## searchController

Search. A `SearchController` reads this key only when it's created with a `client`. Setup function: `client.config.setSetupFunction("searchController", ({ searchController }) => ...)`.

| Key                      | Type      | Default | What it does                                                         |
| ------------------------ | --------- | ------- | -------------------------------------------------------------------- |
| `keepSingleActiveSource` | `boolean` | `true`  | Keeps one search source active at a time instead of running several. |

## See also

- [Configuration](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/configuration/): setting these, setup functions, the resolution order, and who decides what.
- [Advanced: making your own class configurable](https://getstream.io/chat/docs/sdk/react/v15/reference/state/making-your-own-class-configurable/): why your own classes aren't in this tree, and how to give them the same shape.

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v15/reference/state/configuration-tree/](https://getstream.io/chat/docs/sdk/react/v15/reference/state/configuration-tree/).