# Upgrade to v12

## Introducing Threads 2.0

With the release of v12 of our SDK we're also releasing new thread functionality - specifically "thread view", which consists of [`ThreadList`](/chat/docs/sdk/react/v12/components/core-components/thread-list/) and [`Thread`](/chat/docs/sdk/react/v12/components/core-components/thread/) components allowing your users to quickly go over threaded conversations they're part of. To implement this simple view see [thread and channel view guide](/chat/docs/sdk/react/v12/components/utility-components/chat-view/).

### Thread & ThreadManager

Both [`Thread`](https://github.com/GetStream/stream-chat-js/blob/master/src/thread.ts) and [`ThreadManager`](https://github.com/GetStream/stream-chat-js/blob/master/src/thread_manager.ts) are new classes within [`stream-chat` package](https://www.npmjs.com/package/stream-chat) with own logic which updates their respective state objects to which integrators can subscribe to and render their UI accordingly. These classes (or rather instances of these classes) are utilised within React SDK. Read more about accessing state of these classes in our [SDK State Management documentation](/chat/docs/sdk/react/v12/guides/sdk-state-management#thread-and-threadmanager/).

### ThreadList & ThreadListItem

[`ThreadList`](/chat/docs/sdk/react/v12/components/core-components/thread-list/) component represents a [`ThreadManager`](https://github.com/GetStream/stream-chat-js/blob/master/src/thread_manager.ts) instance while [`ThreadListItem`](/chat/docs/sdk/react/v12/components/core-components/thread-list-item/) represents individual [`Thread`](https://github.com/GetStream/stream-chat-js/blob/master/src/thread.ts) instances. UI of both of these components reflects latest state of their appropriate "controllers" but apart from communicating with their controllers via available methods these components do not manage any extra logic.

### ThreadProvider

[`ThreadProvider`](/chat/docs/sdk/react/v12/components/contexts/thread-context#threadprovider/) is an "adapter" which allows existing [`Thread`](/chat/docs/sdk/react/v12/components/core-components/thread/) component to consume methods and state of the [`Thread`](https://github.com/GetStream/stream-chat-js/blob/master/src/thread.ts) instance.

```tsx
<ThreadProvider thread={thread}>
  <Thread />
</ThreadProvider>
```

### ChatView & ChatView.ThreadAdapter

`ChatView` is component itself and a set of components which allow for a drop-in implementation of different chat views - the channel view and thread view. This drop-in solution allows your users to easily switch between said views without having to implement such mechanism yourself. Read more about it in our [`ChatView` documentation](/chat/docs/sdk/react/v12/components/utility-components/chat-view/).

## Introducing WithComponents & Dropping Defaults

We know that component overrides are 90% of our SDK and providing these overrides only through [`Channel`](/chat/docs/sdk/react/v12/components/core-components/channel/) component isn't optimal. In the upcoming minor releases we'll be deprecating component overrides through individual component props and rather provide these overrides through `WithComponents`, you can read more about this component in our [`WithComponents` documentation](/chat/docs/sdk/react/v12/components/contexts/component_context#withcomponents).

## Dropped ComponentContext Defaults

These components are no longer provided through the [`ComponentContext`](/chat/docs/sdk/react/v12/components/contexts/component_context/) as default values but have moved to their respective components:

- `Attachment`
- `DateSeparator`
- `Message`
- `MessageSystem`
- `reactionOptions`
- `UnreadMessagesSeparator`

### Before and After

Previous solution for component overrides:

```tsx
const MessageInputUi1 = () => {
  /*...*/
};
const MessageInputUi2 = () => {
  /*...*/
};

<Channel Input={MessageInputUi1}>
  <Window>
    <MessageList />
    <MessageInput focus />
  </Window>
  <Thread Input={MessageInputUi2} virtualized />
</Channel>;
```

Current solution utilising `WithComponents`:

```tsx
const MessageInputUi1 = () => {
  /*...*/
};
const MessageInputUi2 = () => {
  /*...*/
};

<Channel>
  <WithComponents overrides={{ Input: MessageInputUi1 }}>
    <Window>
      <MessageList />
      <MessageInput focus />
    </Window>
    <WithComponents overrides={{ Input: MessageInputUi2 }}>
      <Thread virtualized />
    </WithComponents>
  </WithComponents>
</Channel>;
```

## Audio recordings transcoding

Until now the audio recordings were transcoded to audio/mp3. As of v12, the MIME-type audio/wav will be the default.
You can still opt-in to MP3 and benefit from the reduced file size and bandwidth usage:

<admonition type="tip">

**Action required**<br/>
To opt into MP3 transcoding follow these steps:

1. The library `@breezystack/lamejs` has to be installed as this is a peer dependency to `stream-chat-react`.

```shell
npm install @breezystack/lamejs
```

```shell
yarn add @breezystack/lamejs
```

2. The MP3 encoder has to be imported separately as a plugin:

```tsx
import { MessageInput } from "stream-chat-react";
import { encodeToMp3 } from "stream-chat-react/mp3-encoder";

<MessageInput
  focus
  audioRecordingConfig={{ transcoderConfig: { encoder: encodeToMp3 } }}
/>;
```

</admonition>

## Unified dialog management

Dialogs will be managed centrally. At the moment, this applies to display of `ReactionSelector` and `MessageActionsBox`. They will be displayed on a transparent overlay that prevents users from opening other dialogs in the message list. Once an option from a dialog is selected or the overlay is clicked, the dialog will disappear. This adjust brings new API and removes some properties from `MessageContextValue`.

### Removed properties from MessageContextValue

- `isReactionEnabled` - served to signal the permission to send reactions by the current user in a given channel. With the current permissions implementation, the permission can be determined by doing the following:

```tsx
import { useMessageContext } from "stream-chat-react";

const { getMessageActions } = useMessageContext();
const messageActions = getMessageActions();
const canReact = messageActions.includes(MESSAGE_ACTIONS.react);
```

- `onReactionListClick` - handler function that toggled the open state of `ReactionSelector` represented by another removed value - `showDetailedReactions`
- `showDetailedReactions` - flag used to decide, whether the reaction selector should be shown or not
- `reactionSelectorRef` - ref to the root of the reaction selector component (served to control the display of the component)

Also prop `messageWrapperRef` was removed as part of the change from `MessageOptions` and `MessageActions` props.

On the other hand, the `Message` prop (configuration parameter) `closeReactionSelectorOnClick` is now available in the `MessageContextValue`.

<admonition type="tip">

If you used any of these values in your customizations, please make sure to adjust your implementation according to the newly recommended use of Dialog API in [Dialog management guide](/chat/docs/sdk/react/v12/guides/dialog-management/).

</admonition>

### New dialog management API

To learn about the new API, please, take a look at our [Dialog management guide](/chat/docs/sdk/react/v12/guides/dialog-management/).

## EmojiPickerIcon extraction to emojis plugin

The default `EmojiPickerIcon` has been moved to emojis plugin from which we already import `EmojiPicker` component.

<admonition type="tip">

**Action required**<br/>
In case you are importing `EmojiPickerIcon` in your code, make sure to adjust the import as follows:

```tsx
import { EmojiPickerIcon } from "stream-chat-react/emojis";
```

</admonition>

## Removal of duplicate uploads state in MessageInput

As of the version 12 of `stream-chat-react` the `MessageInputContext` will not expose the following state variables:

- `fileOrder` - An array of IDs for non-image uploaded attachments. Its purpose was just to keep order in which the attachments were added.
- `imageOrder` - An array of IDs for image uploaded attachments. Its purpose was just to keep order in which the attachments were added.
- `fileUploads` - A mapping of ID to attachment representing the uploaded non-image file.
- `imageUploads` - A mapping of ID to attachment representing the uploaded image file.

These four variables' purpose was to render the attachment previews in a given order. All the non-image attachments were assigned type `"file"` until the message was sent at which point the audio files were assigned type `"audio"` and video file type `"video"`. Also, the attachment objects structure used to change upon submission. Some keys were renamed and other just removed.

The shortcomings of the above approach have been adjusted as follows:

1. All the attachments except the link preview attachments (objects that contain `og_scrape_url` attribute) are now stored in `attachments` array of `MessageInputContext`. Array keeps order and the attachment type can be determined by the `attachment.type` property.

2. The previously removed "local" data is now stored on each attachment object under `localMetadata` key. This key is removed upon submission. Every `localMetadata` object has to at least contain the `id` attribute that allows us to update or remove the given attachment from the state. The attachments that represent an uploaded file has to also include the `localMetadata.file` reference.

3. Attachments representing uploaded files will be identified by the `file` attribute as `attachment.localMetadata.file`. Default attachment types recognized by the SDK are:

- `audio`
- `file`
- `image`
- `video`
- `voiceRecording`

4. The attachment `type` is assigned upon the upload and not upon the submission. Also, there is no renaming of attachment attributes upon submission, but the attachment objects are assigned the attributes that are kept from the upload until the submission. These attributes are:

5. We have removed the following API tied to uploads state from the MessageInput state

- `uploadFile` -> from now on, use `uploadAttachment`
- `uploadImage` -> from now on, use `uploadAttachment`
- `removeFile` -> from now on, use `removeAttachments`
- `removeImage` -> from now on, use `removeAttachments`

The function `uploadNewFiles` has been kept.

To sum up, the attachments management API in MessageInput is from now on only:

- `attachments` - An array that keeps all the message attachment objects except for link previews that should be accessed via [`linkPreviews`](/chat/docs/sdk/react/v12/components/contexts/message_input_context#linkpreviews/) (see the [guide on how to use `linkPreviews`](/chat/docs/sdk/react/v12/guides/customization/link-previews/)).
- `uploadAttachment` - Uploads a single attachment. The provided attachment should contain a `localMetadata` object with `file` (references a `File` instance to be uploaded) and `id` properties.
- `uploadNewFiles` - Expects an array of `File` or `Blob` objects, generates an array of well-formed attachments and uploads the files with `uploadAttachment` function
- `upsertAttachments` - Expects an array of attachment object where each of those should contain `localMetadata.id`. Creates or updates the attachment attributes based on the given id in the `attachments` array of `MessageInputContext`.
- `removeAttachments` - Expects and array of strings representing attachment IDs and removes those attachment objects from the state.

<admonition type="tip">

**Action required**<br/>
Make sure you are not using any of the removed API elements (for example you have implemented a custom `AttachmentPreviewList`):

- `fileOrder`
- `imageOrder`
- `fileUploads`
- `imageUploads`
- `uploadFile`
- `uploadImage`
- `removeFile`
- `removeImage`

</admonition>

## Date & time formatting

The components that display date and time are:

- `DateSeparator` - separates message groups in message lists
- `EventComponent` - displays system messages
- `MessageTimestamp` - displays the creation timestamp for a message in a message list

These components had previously default values for props like `format` or `calendar`. This setup required for a custom formatting to be set up via i18n service, the default values had to be nullified. For a better developer experience we decided to remove the default prop values and rely on default configuration provided via i18n translations. The value `null` is not a valid value for `format`, `calendar` or `calendarFormats` props.

<admonition type="tip">

**Action required**<br/>
If you are not using the default translations provided with the SDK, make sure to follow the [date & time formatting guide](/chat/docs/sdk/react/v12/guides/date-time-formatting/) to verify that your dates are formatted according to your needs.

</admonition>

## Avatar changes

The `Avatar` styles are applied through CSS from the version 12 upwards. Therefore, the following changes were applied:

1. Props `shape` and `size` were removed. Subsequently, the class `str-chat__avatar--${shape}` was removed.

2. Another class we removed is `str-chat__avatar-image--loaded` that was applied to `img` element in the `Avatar` component.

3. New prop `className` has been added to `Avatar`. Integrators can now optionally apply custom styles to custom classes.

4. There have also been added new classes to `Avatar` root `div` in different components:

| Component                                   | `Avatar` root CSS class                   |
| ------------------------------------------- | ----------------------------------------- |
| `ChannelHeader`                             | `str-chat__avatar--channel-header`        |
| `ChannelPreviewMessenger`                   | `str-chat__avatar--channel-preview`       |
| `MessageStatus`                             | `str-chat__avatar--message-status`        |
| `ReactionsList`                             | `stream-chat__avatar--reaction`           |
| `QuotedMessage`                             | `str-chat__avatar--quoted-message-sender` |
| `SearchResultItem`                          | `str-chat__avatar--channel-preview`       |
| `UserItem` rendered by `SuggestionListItem` | `str-chat__avatar--autocomplete-item`     |

5. As a consequence of the `Avatar` props changes, the `TypingIndicator` prop `avatarSize` have been removed as well.

<admonition type="tip">

**Action required**  
1\. Migrate CSS applied to `.str-chat__avatar--${shape}` or re-apply the class through `Avatar` `className` prop.  
2\. Migrate CSS applied to `.str-chat__avatar-image--loaded` to `.str-chat__avatar-image` class.  
3\. If needed, apply custom styles to newly added classes based on the component that renders the `Avatar`.

</admonition>

## Removal of styling props

### Removal of Window's hideOnThread prop

The prop boolean `hideOnThread` enabled us to control, whether class `str-chat__main-panel--hideOnThread` was attached to `Window` component's root `<div/>`. By assigning this class a CSS rule `display: none` in the default SDK's stylesheet we hid the contents of `Window`. We decided to simplify the logic in this case:

1. class `str-chat__main-panel--hideOnThread` was replaced by class `str-chat__main-panel--thread-open`
2. the class `str-chat__main-panel--thread-open` is attached to the root `<div/>` always, when thread is open
3. the default value of `hideOnThread` prop was `false` (`Window` contents was not hidden upon opening a thread) and so integrators still have to opt in to hiding the contents upon opening a thread by adding rule `display: none` to `str-chat__main-panel--thread-open` class

<admonition type="tip">

**Action required**
If your application renders `Window` with `hideOnThread` enabled, and you want to keep this behavior add the following rule to your CSS:

```css
.str-chat__main-panel--thread-open {
  display: none;
}

.str-chat__main-panel--thread-open + .str-chat__thread {
  // occupy the whole space previously occupied by the main message list container
  flex: 1;
}
```

</admonition>

### Removal of Thread's fullWidth prop

Setting the `fullWidth` value to `true` let to assignment of class `str-chat__thread--full` to the `Thread` component's root `<div/>`. This class had support in the SDK's legacy stylesheet only. With the approach of avoiding styling React components via props, the prop has been removed along with the legacy stylesheet. Read more about the the stylesheet removal in the [section **Removal of deprecated components**](#removal-of-deprecated-components).

## Removal of deprecated components

### Attachment rendering utility functions

The attachment rendering functions were replaced with their component equivalents:

<admonition type="tip">

**Action required**  
Replace the render functions in your custom components with container components alternatives.

</admonition>

| Rendering function                | Component equivalent         |
| --------------------------------- | ---------------------------- |
| `renderAttachmentWithinContainer` | `AttachmentWithinContainer`  |
| `renderAttachmentActions`         | `AttachmentActionsContainer` |
| `renderGallery`                   | `GalleryContainer`           |
| `renderImage`                     | `ImageContainer`             |
| `renderCard`                      | `CardContainer`              |
| `renderAudio`                     | `AudioContainer`             |
| `renderMedia`                     | `MediaContainer`             |

## Change import of default styles

Until now, it was possible to import two stylesheets as follows:

```tsx
import "stream-chat-react/dist/css/v1/index.css";
```

Or

```tsx
import "stream-chat-react/dist/css/v2/index.css";
```

The legacy stylesheet has been removed from the SDK bundle, and therefore it is only possible to import one stylesheet from now on:

```tsx
import "stream-chat-react/dist/css/v2/index.css";
```

<admonition type="tip">

**Action required**  
Make sure you are importing the default styles correctly as `import 'stream-chat-react/dist/css/v2/index.css';`

</admonition>

## Removal of legacy styles

With the version 10 of `stream-chat-react` new stylesheet has been introduced. The stylesheet used previously became a legacy stylesheet. Legacy stylesheet had often times CSS classes and SDK components, that were not supported with the new stylesheet. Now, the legacy stylesheet and corresponding CSS classes and SDK component are being removed.

<admonition type="warning">

These changes will impact you only if you have imported the CSS as one of the following (you have used the legacy styles):

```tsx
import "stream-chat-react/css/index.css";
```

```tsx
import "@stream-io/stream-chat-css/dist/css/index.css";
```

</admonition>

### Removal of themeVersion from ChatContext

Supporting two stylesheet lead to introduction of a flag `themeVersion` into the `ChatContext`. This flag is no more necessary and has been removed from the context value.

<admonition type="tip">

**Action required**  
Make sure you are not using `themeVersion` in your custom components.

</admonition>

### Removal of styles related Chat props

With legacy stylesheet we have removed legacy approach to applying styles via component props. Two `Chat` component props were removed as a consequence:

- `customStyles`
- `darkMode`

Also associated parts of code were removed:

- `Theme` type
- `useCustomStyles` hook

<admonition type="tip">

**Action required**  
1\. The styles applied through `customStyles` should be applied through custom CSS.  
2\. Theme (not only dark theme) can be through `Chat` prop `theme` instead of `darkMode`

</admonition>

### Removal from ComponentContext

- `AutocompleteSuggestionHeader` - the up-to-date SDK markup does not count with a header in the `ChatAutoComplete` suggestion list

<admonition type="tip">

**Action required**  
Make sure you are passing these custom components to the `Channel` component.

</admonition>

### Removal of legacy components

The following components are not available anymore as they were related to legacy stylesheet and are not used by the latest SDK components.

<admonition type="tip">

**Action required**  
1\. Remove imports of these components from `stream-chat-react` in your custom components.  
2\. If importing `SendIconV2` rename it to `SendIcon`.  
3\. Remove the listed classes if used in your CSS.

</admonition>

| Component                                                          | Details                                                                                                                                                        | Removed CSS classes                                           |
| ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `DefaultSuggestionListHeader`                                      | rendered only with legacy stylesheet in the `ChatAutoComplete`. As a consequence the `AutocompleteSuggestionHeader` prop has been removed from `Channel` props |                                                               |
| Icons rendered `Message` component when legacy styles applied      | `ReplyIcon`, `DeliveredCheckIcon`, `ErrorIcon`                                                                                                                 |                                                               |
| Icons rendered `MessageInput` component when legacy styles applied | `EmojiIconLarge`, `EmojiIconSmall`, `FileUploadIcon`, `FileUploadIconFlat`, `SendIconV1` (`SendIconV2` renamed to `SendIcon`)                                  |                                                               |
| `MessageInputSmall`                                                | Used to be rendered in `Thread`, but was deprecated since v10 and replaced by `MessageInputFlat`                                                               | all the classes starting with `str-chat__small-message-input` |
| `UploadsPreview`                                                   | Used to be rendered in `MessageInput` but was deprecated since v10 and replaced with `AttachmentPreviewList`                                                   |                                                               |
| `FilePreviewer` was rendered by `UploadsPreview`                   | Used by component removed from the SDK                                                                                                                         |                                                               |
| `ImagePreviewer` was rendered by `UploadsPreview`                  | Used by component removed from the SDK                                                                                                                         |                                                               |
| `AttachmentIcon`                                                   | Not used by the SDK                                                                                                                                            |                                                               |
| `PictureIcon`                                                      | Not used by the SDK                                                                                                                                            |                                                               |
| `FileUploadButton`                                                 | Not used by the SDK                                                                                                                                            |                                                               |
| `ImageUploadButton`                                                | Not used by the SDK                                                                                                                                            |                                                               |
| `ThumbnailPlaceholder`                                             | Not used by the SDK                                                                                                                                            |                                                               |
| `Thumbnail`                                                        | Not used by the SDK                                                                                                                                            |                                                               |

### Removal of legacy attachment file icons

The `FileIcon` component does not accept argument `version` anymore. This parameter used to determine the file icon set. There were two sets - version `'1'` and `'2'`. The icons of version `'1'` have been rendered with legacy stylesheets in the SDK components. The icons displayed under the version `'1'` have been removed now.

<admonition type="tip">

**Action required**  
Remove prop `version` if the `FileIcon` is used in your custom components.

</admonition>

### Removal of legacy CSS classes

We have removed classes that were used in the legacy CSS stylesheet only and thus are redundant. We recommend to use classes that were already available previously and are used by the SDK stylesheet:

<admonition type="tip">

**Action required**  
Replace the removed classes with their alternatives in the custom CSS.

</admonition>

| Component                                                                                 | Class removed                                                                       | Class to be used instead                                                                |
| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `MediaContainer`                                                                          | `str-chat__attachment-media`                                                        | `str-chat__attachment`                                                                  |
| suggestion list in `ReactTextAreaAutocomplete`                                            | `rta__autocomplete`                                                                 | `str-chat__suggestion-list-container`                                                   |
| `Avatar` root `<div/>`                                                                    | `str-chat__avatar--circle`, `str-chat__avatar--square`, `str-chat__avatar--rounded` | `str-chat__avatar` possibly combined with custom class                                  |
| `Avatar` element `<img/>`                                                                 | `str-chat__avatar-image--loaded`                                                    |                                                                                         |
| `Channel` root `<div/>`                                                                   | `str-chat-channel`                                                                  | `str-chat__channel`                                                                     |
| `ChannelHeader` root `<div/>`                                                             | `str-chat__header-livestream`                                                       | `str-chat__channel-header`                                                              |
| `ChannelHeader` root `<div/>` children                                                    | `str-chat__header-livestream-left`                                                  | `str-chat__channel-header-end`                                                          |
| `ChannelHeader` root `<div/>` children                                                    | `str-chat__header-livestream-left--title`                                           | `str-chat__channel-header-title`                                                        |
| `ChannelHeader` root `<div/>` children                                                    | `str-chat__header-livestream-left--subtitle`                                        | `str-chat__channel-header-subtitle`                                                     |
| `ChannelHeader` root `<div/>` children                                                    | `str-chat__header-livestream-left--members`                                         | `str-chat__channel-header-info`                                                         |
| `ChannelList` root `<div/>`                                                               | `str-chat-channel-list`                                                             | `str-chat__channel-list`                                                                |
| `ChannelPreviewMessenger` root `<div/>` children                                          | `str-chat__channel-preview-messenger--right`                                        | `str-chat__channel-preview-end`                                                         |
| `SearchResults` root `<div/>` children                                                    | `str-chat__channel-search-container`                                                | `str-chat__channel-search-result-list`                                                  |
| `SuggestionList` (rendered by `ChatAutoComplete`) container `<div/>`                      | `str-chat__emojisearch`                                                             | `str-chat__suggestion-list-container`                                                   |
| `SuggestionList` (rendered by `ChatAutoComplete`) root `<div/>`                           | `str-chat__emojisearch__list`                                                       | `str-chat__suggestion-list`                                                             |
| `SuggestionListItem` (rendered by `SuggestionList`) root `<div/>`                         | `str-chat__emojisearch__item`                                                       | `str-chat__suggestion-list-item`                                                        |
| `EmojiPicker` root `<div/>`                                                               | `str-chat__emojiselect-wrapper` (only applied with legacy styles)                   | `str-chat__message-textarea-emoji-picker`                                               |
| `EmojiPicker` button                                                                      | `str-chat__input-flat-emojiselect` (only applied with legacy styles)                | `str-chat__emoji-picker-button`                                                         |
| `Emoji` (rendered by `Message`)                                                           | `inline-text-emoji`                                                                 | the `<p/>` element has been removed, no substitute class                                |
| `MessageRepliesCountButton` (rendered by `Message`) root `<div/>`                         | `str-chat__message-simple-reply-button`                                             | `str-chat__message-replies-count-button-wrapper`                                        |
| `Message` wrapper `<div/>` around `MessageStatus` & `MessageTimestamp`                    | `str-chat__message-data`, `str-chat__message-simple-data`                           | `str-chat__message-metadata`                                                            |
| `QuotedMessage` root `<div/>`                                                             | `quoted-message`                                                                    | `str-chat__quoted-message-preview`                                                      |
| `QuotedMessage` bubble                                                                    | `quoted-message-inner`                                                              | `str-chat__quoted-message-bubble`                                                       |
| `EditMessageForm`                                                                         | `str-chat__edit-message-form-options`                                               | no alternative                                                                          |
| `EditMessageForm`                                                                         | `str-chat__fileupload-wrapper`                                                      | no alternative                                                                          |
| `EditMessageForm`                                                                         | `str-chat__input-fileupload`                                                        | no alternative                                                                          |
| `MessageInputFlat` root `<div/>`                                                          | all classes starting with `str-chat__input-flat`                                    | see the current implementation of `MessageInputFlat`                                    |
| `QuotedMessagePreviewHeader` (rendered by `QuotedMessagePreviewHeader`) root `<div/>`     | `quoted-message-preview-header`                                                     | `str-chat__quoted-message-preview-header`                                               |
| `QuotedMessagePreviewHeader` (rendered by `QuotedMessagePreviewHeader`) child `<button/>` | `str-chat__square-button`                                                           | `str-chat__quoted-message-remove`                                                       |
| `QuotedMessagePreview` root `<div/>`                                                      | `quoted-message-preview`                                                            | no alternative                                                                          |
| `QuotedMessagePreview`                                                                    | `quoted-message-preview-content`                                                    | `str-chat__quoted-message-preview`                                                      |
| `QuotedMessagePreview`                                                                    | `quoted-message-preview-content-inner`                                              | `str-chat__quoted-message-bubble`                                                       |
| `MessageList`                                                                             | `str-chat__thread--full`                                                            | no alternative                                                                          |
| `InfiniteScroll` rendered by `MessageList`                                                | `str-chat__reverse-infinite-scroll`                                                 | `str-chat__message-list-scroll`                                                         |
| `ScrollToBottomButton`                                                                    | `str-chat__message-notification-right`                                              | `str-chat__message-notification-scroll-to-latest`                                       |
| `ScrollToBottomButton`                                                                    | `str-chat__message-notification-scroll-to-latest-unread-count`                      | `str-chat__jump-to-latest-unread-count`                                                 |
| `ReactionsListModal`                                                                      | `emoji`                                                                             | `str-chat__message-reaction-emoji` or `str-chat__message-reaction-emoji--with-fallback` |
| `SimpleReactionList`                                                                      | `str-chat__simple-reactions-list-tooltip`                                           | no alternative - markup removal                                                         |
| `Thread`                                                                                  | `str-chat__list--thread`                                                            | `str-chat__thread-list`                                                                 |
| `ThreadHeader`                                                                            | `str-chat__square-button`                                                           | `str-chat__close-thread-button`                                                         |
| `TypingIndicator`                                                                         | `str-chat__typing-indicator__avatars`                                               | no alternative - markup removal                                                         |

### Added classes

Migration to non-legacy styles leads to rendering of markup with the following classes:

<admonition type="tip">

**Action required**  
Verify your app layout is not broken and adjust the CSS if necessary.

</admonition>

| Class                        | Details                                                                     |
| ---------------------------- | --------------------------------------------------------------------------- |
| `str-chat__main-panel-inner` | A `<div/>` with this class wraps `MessageList` and `VirtualizedMessageList` |

### Removed types

<admonition type="tip">

**Action required**  
Import type alternatives if necessary.

</admonition>

| Removed type               | Details                                                                                                     | To be used instead              |
| -------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------- |
| `CustomMessageActionsType` | Props for component `CustomMessageActionsList`, that renders custom messages actions in `MessageActionsBox` | `CustomMessageActionsListProps` |

### TypingIndicator component without Avatars

The `TypingIndicator` component does not render avatars as it used to with legacy stylesheet. Therefore, its prop `Avatar` has been removed.

<admonition type="tip">

**Action optional**  
Provide custom `TypingIndicator` through the `Channel` prop.

</admonition>

## Updated browser target

Version 12 targets browsers that support ES2020. In particular, the code includes `async` functions, optional chaining (`?.`), and nullish coalescing (`??`). These features have been supported by all major desktop and mobile browsers for years, so it made sense for us to raise the baseline.

The following browsers [support ES2020](https://caniuse.com/?feats=mdn-javascript_operators_optional_chaining,mdn-javascript_operators_nullish_coalescing,mdn-javascript_builtins_globalthis,es6-module-dynamic-import,bigint,mdn-javascript_builtins_promise_allsettled,mdn-javascript_builtins_string_matchall,mdn-javascript_statements_export_namespace,mdn-javascript_operators_import_meta) and should be able to run the SDK as-is:

- Chrome 80 and later
- Safari 14.1 and later on desktops, 14.5 and later on iOS
- Edge 80 and later
- Firefox 80 and later

If you need to support older browsers, you should transpile your bundle using `babel` or a similar tool.

<admonition type="tip">

**Action optional**  
If you're targeting browsers that don't support ES2020, use a transpilation tool like `babel` to process your bundle.

</admonition>

## Browser bundle removed from the package

Prior to version 12, we included the browser bundle in the package, which could be added to the page using the `<script>` tag. We no longer ship the browser bundle.

Using the browser bundle was never recommended, and it was mostly for testing purposes. If you still want to quickly add the SDK using the `<script>` tag, you can use services such as [https://esm.sh/](https://esm.sh/) or [https://www.unpkg.com/](https://unpkg.com/).

Installing the package from NPM and then bundling it with your application is still the best way to use the SDK.


---

This page was last updated at 2026-04-22T11:55:38.125Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v12/release-guides/upgrade-to-v12/](https://getstream.io/chat/docs/sdk/react/v12/release-guides/upgrade-to-v12/).