import { Meta } from '@storybook/blocks'; # Migration from 2.0 to 3.0 Version 3 of the Amazon Chime React Component Library makes small changes to the interface of the library to make it more customizable. ### IMPORTANT - Version 3 of the library also requires a dependency to version 3.0.0 or higher of the amazon-chime-sdk-js. In many cases, you will need to adjust your application code because interface parameters to root providers like `MeetingProvider` are updated. ## Installation Installation involves adjusting your package.json to depend on version 3.x.x ``` npm uninstall amazon-chime-sdk-component-library-react amazon-chime-sdk-js npm install --save amazon-chime-sdk-component-library-react@3 amazon-chime-sdk-js@3 ``` ## What's New Amazon Chime SDK React Components Library v3 includes major improvements for component style customization, `MeetingProvider/MeetingManager` configuration, device management, WebRTC metrics and logger. - **Component style customization**: Improve components for easier customization of style. Check out our [styling guide](https://aws.github.io/amazon-chime-sdk-component-library-react/?path=/story/styling-guide--page) for more information. - **`MeetingProvider/MeetingManager` configuration**: Improve `MeetingProvider`, `MeetingManager` and `MeetingManager.join()` API to allow configuring a meeting session right before joining a meeting instead of when `MeetingProvider` mounts. - **Device management**: Improve `types` for device selection components to better support basic and transformed devices. Remove `useSelectAudioInputDevice`, `useSelectVideoInputDevice`, and `useSelectAudioOutputDevice` hooks to standardize device selection through `MeetingManager` and throw error when selection fails. - **WebRTC metrics**: Publish the standardized WebRTC metrics for all supported browsers. Deprecate `useBandwidthMetrics` hook in favor of `useMediaStreamMetrics` hook. - **Logger**: Add `LoggerProvider` and `useLogger` components to enable universal logging in component library. Check out our [CHANGELOG for 3.0.0](https://github.com/aws/amazon-chime-sdk-component-library-react/blob/2e9ae19fb6ea72a6611a7d7188744c1db45d8e09/CHANGELOG.md#L20) for more details. ### `MeetingProvider` props change `MeetingProvider` no longer takes the following props: - `MeetingSessionConfiguration` properties: - `VideoDownlinkBandwidthPolicy` - `VideoUplinkBandwidthPolicy` - `simulcastEnabled` - `reconnectTimeoutMs` - `keepLastFrameWhenPaused` - Other props: - `deviceLabels` - `eventController` - `enableWebAudio` - `activeSpeakerPolicy` These props can rather be updated by passing the `MeetingSessionConfiguration` object or by passing `options` props to `meetingManager.join()` method. You can learn more about the `meetingManager.join()` method here: [MeetingManager](/docs/sdk-providers-meetingmanager--page). #### Examples ##### VideoDownlinkBandwidthPolicy The following example uses `VideoDownlinkBandwidthPolicy` property as an example to showcase the change. Before in 2.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; const App = () => { // MyVideoDownlinkBandwidthPolicy is a custom class implementing VideoDownlinkBandwidthPolicy interface from amazon-chime-sdk-js. const videoDownlinkBandwidthPolicy = new MyVideoDownlinkBandwidthPolicy(); const meetingConfig = { videoDownlinkBandwidthPolicy, }; return ( ); }; const MyApp = () => { const meetingManager = useMeetingManager(); await meetingManger.join({ data.Meeting, data.Attendee }); await meetingManager.start(); return (
...
); }; ``` After in 3.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; import { MeetingSessionConfiguration } from 'amazon-chime-sdk-js'; const App = () => { return ( ); }; const MyApp = () => { // MyVideoDownlinkBandwidthPolicy is a custom class implementing VideoDownlinkBandwidthPolicy interface from amazon-chime-sdk-js. const videoDownlinkBandwidthPolicy = new MyVideoDownlinkBandwidthPolicy(); const meetingSessionConfiguration = new MeetingSessionConfiguration( data.Meeting, data.Attendee ); meetingSessionConfiguration.videoDownlinkBandwidthPolicy = videoDownlinkBandwidthPolicy; const meetingManager = useMeetingManager(); await meetingManager.join(meetingSessionConfiguration); await meetingManager.start(); return
...
; }; ``` ##### simulcastEnabled One thing to note is that the `MeetingProvider` props might not have the same mapping with `MeetingSessionConfiguration` properties. For example, `simulcastEnabled` in `MeetingProvider` and the property in `MeetingSessionConfiguration` is different. The following code example should help remove any confusion. Before in 2.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; const App = () => { const meetingConfig = { simulcastEnabled: false, }; return( ); }; const MyApp = () => { const meetingManager = useMeetingManager(); await meetingManger.join({ data.Meeting, data.Attendee }); await meetingManager.start(); return (
...
); }; ``` After in 3.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; import { MeetingSessionConfiguration } from 'amazon-chime-sdk-js'; const App = () => { return ( ); }; const MyApp = () => { const meetingSessionConfiguration = new MeetingSessionConfiguration( data.Meeting, data.Attendee ); meetingSessionConfiguration.enableSimulcastForUnifiedPlanChromiumBasedBrowsers = false; const meetingManager = useMeetingManager(); await meetingManager.join(meetingSessionConfiguration); await meetingManager.start(); return
...
; }; ``` ##### enableWebAudio The following example uses `enableWebAudio` property as an example to showcase the change. `enableWebAudio` is chosen here because it is one of the properties that is affected and it is not part of `MeetingSessionConfiguration`. Before in 2.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; const App = () => { const meetingConfig = { enableWebAudio: true, }; return( ); }; const MyApp = () => { const meetingManager = useMeetingManager(); await meetingManger.join({ data.Meeting, data.Attendee }); await meetingManager.start(); return (
...
); }; ``` After in 3.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; import { MeetingSessionConfiguration } from 'amazon-chime-sdk-js'; const App = () => { return ( ); }; const MyApp = () => { const meetingSessionConfiguration = new MeetingSessionConfiguration( data.Meeting, data.Attendee ); const options = { enableWebAudio: true, }; const meetingManager = useMeetingManager(); await meetingManager.join(meetingSessionConfiguration, options); await meetingManager.start(); return
...
; }; ``` ### `MeetingManager` `join` method parameter change In V3, `MeetingManager`'s `join` method takes `MeetingSessionConfiguration` and `options` as parameter. `meetingInfo` and `attendeeInfo` parameters are removed from the interface and are rather passed to the constructor of `MeetingSessionConfiguration`. Before in 2.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; const MyApp = () => { const meetingManager = useMeetingManager(); await meetingManager.join({ data.Meeting, data.Attendee }); await meetingManager.start(); }; ``` After in 3.x: ```jsx import { useMeetingManager } from 'amazon-chime-sdk-component-library-react'; import { MeetingSessionConfiguration } from 'amazon-chime-sdk-js'; const MyApp = () => { const meetingSessionConfiguration = new MeetingSessionConfiguration( data.Meeting, data.Attendee ); const meetingManager = useMeetingManager(); await meetingManager.join(meetingSessionConfiguration); await meetingManager.start(); }; ``` ### Updating `EventReporter` to `EventController` Before in 2.x: ```jsx const MyApp = () => { const meetingManager = useMeetingManager(); const joinMeeting = async () => { const response = await fetch('/my-meetings-endpoint'); const data = await response.json(); const joinData = { meetingInfo: data.Meeting, attendeeInfo: data.Attendee, eventReporter: new NoOpEventReporter(), }; try { await meetingManager.join(joinData); await meetingManager.start(); } catch { console.error('Something went wrong'); } }; return ( ; ); }; ``` After in 3.x: ```jsx const MyApp = () => { const meetingManager = useMeetingManager(); const joinMeeting = async () => { const response = await fetch('/my-meetings-endpoint'); const data = await response.json(); const meetingSessionConfiguration = new MeetingSessionConfiguration(data.Meeting, data.Attendee); const eventController = new DefaultEventController( meetingSessionConfiguration, new ConsoleLogger('SDK', LogLevel.WARN), new NoOpEventReporter() ); const options = { eventController }; try { await meetingManager.join( meetingSessionConfiguration, options ); await meetingManager.start(); } catch { console.error('Something went wrong'); } }; return ( ; ); }; ``` ## WebRTC Metrics Change ### Deprecation of `useBandwidthMetrics` hook The `useBandwidthMetrics` hook exposes two WebRTC metrics: - `availableOutgoingBandwidth` - `availableIncomingBandwidth`. The `useMediaStreamMetrics` covers all metrics of `useBandwidthMetrics` hook, so we have deprecated it in V3. Before in 2.x: To get the `availableOutgoingBandwidth` and `availableIncomingBandwidth` in V2. ```jsx import React from 'react'; import { MeetingProvider, useBandwidthMetrics, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { const metrics = useBandwidthMetrics(); return ( <>

Incoming Bandwidth: {metrics.availableIncomingBandwidth}

Outgoing Bandwidth: {metrics.availableOutgoingBandwidth}

); }; ``` After in 3.x: To get the `availableOutgoingBandwidth` and `availableIncomingBandwidth` in V3. ```jsx import React from 'react'; import { MeetingProvider, useMediaStreamMetrics, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { const metrics = useMediaStreamMetrics(); return ( <>

Incoming Bandwidth: {metrics.availableIncomingBandwidth}

Bandwidth Outgoing: {metrics.availableOutgoingBandwidth}

); }; ``` ## Enable logging using `useLogger` and `LoggerProvider` Please check documentation on [LoggerProvider](https://aws.github.io/amazon-chime-sdk-component-library-react/?path=/story/sdk-providers-loggerprovider--page) for more information on its usage. ## StyledComponent ### DefaultTheme Interface In V3, we have renamed the `global` property of `DefaultTheme` Interface to `globalStyle` to avoid conflict with reserved keyword `global`. When you implement your own theme, you need to use `globalStyle` instead of `global`. ## Device ### API Changes In V3, some of device management APIs, hooks and types have been renamed for more accurate description. To migrate, use new names summarized in table below. | Before in 2.x | After in 3.x | | --------------------------------------------------------------------- | --------------------------------------------------------------------- | | DevicePermissionStatus | DeviceLabelTriggerStatus | | DevicePermissionStatus.UNSET | DevicePermissionStatus.UNTRIGGERED | | useDevicePermissionStatus | useDeviceLabelTriggerStatus | | | | | MeetingManager.devicePermissionStatus | MeetingManager.deviceLabelTriggerStatus | | | | | MeetingManager.selectAudioInputDevice() | MeetingManager.startAudioInputDevice() | | MeetingManager.selectAudioOutputDevice() | MeetingManager.startAudioOutputDevice() | | MeetingManager.selectVideoInputDevice() | MeetingManager.startVideoInputDevice() | | | | | MeetingManager.devicePermissionsObserver | MeetingManager.deviceLabelTriggerStatusObservers | | MeetingManager.subscribeToDevicePermissionStatus() | MeetingManager.subscribeToDeviceLabelTriggerStatus() | | MeetingManager.unsubscribeFromDevicePermissionStatus() | MeetingManager.unsubscribeFromDeviceLabelTriggerStatus() | | | | | MeetingManager.deviceLabelTriggerChangeObservers | MeetingManager.deviceLabelTriggerObservers | | MeetingManager.subscribeToDeviceLabelTriggerChange() | MeetingManager.subscribeToDeviceLabelTrigger() | | MeetingManager.unsubscribeFromDeviceLabelTriggerChange() | MeetingManager.unsubscribeFromDeviceLabelTrigger() | #### New API for Handling Video Input Device Switching The original `selectedVideoInputDevice` method in V2 has been renamed to `startVideoInputDevice` in V3, because this method actually starts the device after selection. In V3, we have added a new method `selectVideoInputDevice(device: VideoInputDevice)` in `MeetingManager`. This new method only updates the `selectedVideoInputDevice` with the given `device` and publishes this update via `selectedVideoInputDeviceObservers`. This method is suitable for switching cameras without turning camera on. #### Throw Error When Device Selection APIs Fail In V2, we added `selectDeviceError` to `useAudioInputs` and `useVideoInputs` hook to get the error of `selectAudioInputDevice` and `selectVideoInputDevice` API from client side when they fail. In V3, we remove `selectDeviceError` from these hooks. And now `startAudioInputDevice`, `startAudioOutputDevice` and `startVideoInputDevice` throw errors directly when they fail. Before in 2.x: ```jsx import React from 'react'; import { MeetingProvider, useMeetingManager, useVideoInputs, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { const meetingManager = useMeetingManager(); const { selectDeviceError } = useVideoInputs(); const handleClick = async (): => { await meetingManager.selectVideoInputDevice('deviceId'); }; return ( {selectDeviceError &&

{selectDeviceError?.message}

} ); }; ``` After in 3.x: ```jsx import React from 'react'; import { MeetingProvider, useMeetingManager, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { const meetingManager = useMeetingManager(); const handleClick = async (): => { try { await meetingManager.startVideoInputDevice('deviceId'); } catch (error) { // Handle device selection error. console.error('Failed to select video input device', error); } }; return ( ); }; ``` ### Update Type of Selected Device in MeetingManager In V3, we have improved the `type` for selected device in `MeetingManager` and corresponding components and hooks. #### MeetingManager Properties Change ```ts // Before in 2.x selectedAudioOutputDevice: string | null; selectedAudioInputDevice: string | null; selectedVideoInputDevice: string | null; // After in 3.x selectedAudioOutputDevice: string | null; selectedAudioInputDevice: AudioInputDevice | undefined; selectedVideoInputDevice: VideoInputDevice | undefined; ``` ```ts type Device = string | MediaTrackConstraints | MediaStream; type AudioInputDevice = Device | AudioTransformDevice | null; type VideoInputDevice = Device | VideoTransformDevice; ``` #### Hooks Return Values Change Before in 2.x ```js // Selected audio output device. The type is `string | null` const { selectedDevice } = useAudioOutputs(); // Selected audio input device. The type is `string | null` const { selectedDevice } = useAudioInputs(); // Selected video input device. The type is `string | null` const { selectedDevice } = useVideoInputs(); ``` After in 3.x ```js // Selected audio output device. The type is `string | null` const { selectedDevice } = useAudioOutputs(); // Selected audio input device. The type is `AudioInputDevice | undefined` const { selectedDevice } = useAudioInputs(); // Selected video input device. The type is `VideoInputDevice | undefined` const { selectedDevice } = useVideoInputs(); ``` ### Remove `useSelectAudioInputDevice`, `useSelectAudioOutputDevice` and `useSelectVideoInputDevice` hook In V3, we have removed `useSelectAudioInputDevice`, `useSelectAudioOutputDevice` and `useSelectVideoInputDevice` hook. These hooks just exposed device selection APIs from `MeetingManager`, thus they were redundant. Before in 2.x: ```jsx import React from 'react'; import { MeetingProvider, useSelectVideoInputDevice, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { const selectVideoInput = useSelectVideoInputDevice(); const handleClick = async () => { await selectVideoInput('device-id'); }; return ( ); }; ``` After in 3.x: ```jsx import React from 'react'; import { MeetingProvider, useMeetingManager, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { const meetingManager = useMeetingManager(); const handleClick = async () => { try { await meetingManager.startVideoInputDevice('device-id'); } catch (error) { // Handle device selection failure here console.error('Failed to start video input device'); } }; return ( ); }; ``` ### Remove Preset Device Selection Options In V3, we have removed preset device selection options: - "None", "440 Hz" for audio input device. - "None", "Blue" and "SMTP Color Bars" for video input device. The detailed changes are: - Remove `appendSampleDevices` from Props of `CameraSelection`, `MicSelection`, `AudioInputControl`, `AudioInputVFcontrol`, and `VideoInputControl`. - Remove `additionalDevices` from Props of `useAudioInputs` and `useVideoInputs` hook. - Remove `DeviceConfig` type. #### Components Before in 2.x: ```jsx import React from 'react'; import { MeetingProvider, CameraSelection, } from 'amazon-chime-sdk-component-library-react'; const App = () => { return ( {/* If you don't want preset device selection options. */} ); }; ``` After in 3.x: ```jsx import React from 'react'; import { MeetingProvider, CameraSelection, } from 'amazon-chime-sdk-component-library-react'; const App = () => { return ( {/* In V3, `CameraSelection` component no longer supports preset device selection options. */} ); }; ``` #### Hooks Before in 2.x: ```tsx import React from 'react'; import { MeetingProvider, useVideoInputs, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { const videoInputConfig: DeviceConfig = { additionalDevices: false, }; // `devices` does not contain preset device selection options. const { devices } = useVideoInputs(videoInputConfig); const items = devices.map((device) => (
  • {device.label}
  • )); return (

    Devices

    ); }; ``` After in 3.x: ```jsx import React from 'react'; import { MeetingProvider, useVideoInputs, } from 'amazon-chime-sdk-component-library-react'; const App = () => ( ); const MyChild = () => { // In V3, `useVideoInputs` hook no longer supports preset device selection options. const { devices } = useVideoInputs(); const items = devices.map((device) => (
  • {device.label}
  • )); return (

    Devices

    ); }; ```