> ## Documentation Index
> Fetch the complete documentation index at: https://docs.daily.co/llms.txt
> Use this file to discover all available pages before exploring further.

# DailyStreamingLayoutConfig

> Layout configuration for cloud recordings and live streams. A discriminated union keyed on the preset field.

`DailyStreamingLayoutConfig` controls how participant video is composed when cloud recording or live streaming. It is a discriminated union — the `preset` field determines which layout is used and which additional fields are available.

```typescript theme={null}
type DailyStreamingLayoutConfig =
  | { preset: 'default';               /* ... */ }
  | { preset: 'single-participant';    /* ... */ }
  | { preset: 'active-participant';    /* ... */ }
  | { preset: 'portrait';              /* ... */ }
  | { preset: 'audio-only';            /* ... */ }
  | { preset: 'raw-tracks-audio-only'; /* ... */ }
  | { preset: 'custom';                /* ... */ }
```

Pass a layout config via the `layout` field of [`DailyStreamingOptions`](/reference/react-native/types/daily-streaming-options) when calling [`startRecording()`](/reference/react-native/instance-methods/start-recording), [`updateRecording()`](/reference/react-native/instance-methods/update-recording), [`startLiveStreaming()`](/reference/react-native/instance-methods/start-live-streaming), or [`updateLiveStreaming()`](/reference/react-native/instance-methods/update-live-streaming).

<Note>
  `DailyLiveStreamingLayoutConfig` is the same union with one difference: the `audio-only` preset is not available for live streaming.
</Note>

***

## participants

Several presets accept an optional `participants` config that controls which participants are included in the composition and in what order.

<ResponseField name="participants.video" type="string[]">
  Optional. An ordered list of participant `session_id` values to include in the video composition. Participants not in this list are excluded.
</ResponseField>

<ResponseField name="participants.audio" type="string[]">
  Optional. An ordered list of participant `session_id` values to include in the audio mix.
</ResponseField>

<ResponseField name="participants.sort" type="string">
  Optional. Sort method for participants. Currently only `'active'` is supported, which sorts by recent speaking activity.
</ResponseField>

***

## Presets

### default

Shows up to `max_cam_streams` participant camera tiles in a grid. This is the default if no layout is specified.

<ResponseField name="preset" type="string">
  Always `"default"`.
</ResponseField>

<ResponseField name="max_cam_streams" type="number">
  Optional. Maximum number of camera tiles to show. Defaults to 9.
</ResponseField>

<ResponseField name="participants" type="DailyStreamingParticipantsConfig">
  Optional. See [participants](#participants) above.
</ResponseField>

```json theme={null}
{ "preset": "default", "max_cam_streams": 6 }
```

***

### single-participant

Fills the frame with one participant's camera feed.

<ResponseField name="preset" type="string">
  Always `"single-participant"`.
</ResponseField>

<ResponseField name="session_id" type="string">
  The `session_id` of the participant to feature.
</ResponseField>

```json theme={null}
{ "preset": "single-participant", "session_id": "abc123" }
```

***

### active-participant

Fills the frame with the currently active speaker's camera feed.

<ResponseField name="preset" type="string">
  Always `"active-participant"`.
</ResponseField>

<ResponseField name="participants" type="DailyStreamingParticipantsConfig">
  Optional. See [participants](#participants) above.
</ResponseField>

```json theme={null}
{ "preset": "active-participant" }
```

***

### portrait

Stacks participant tiles vertically, optimized for portrait (mobile) aspect ratios.

<ResponseField name="preset" type="string">
  Always `"portrait"`.
</ResponseField>

<ResponseField name="variant" type="string">
  Optional. Layout variant: `'vertical'` (stacked column) or `'inset'` (active speaker fills the frame with a small inset tile). Defaults to `'vertical'`.
</ResponseField>

<ResponseField name="max_cam_streams" type="number">
  Optional. Maximum number of camera tiles to show.
</ResponseField>

<ResponseField name="participants" type="DailyStreamingParticipantsConfig">
  Optional. See [participants](#participants) above.
</ResponseField>

```json theme={null}
{ "preset": "portrait", "variant": "inset" }
```

***

### audio-only

Records audio without any video composition.

<Note>
  Available for cloud recordings only. Not supported for live streaming — use `DailyStreamingLayoutConfig` rather than `DailyLiveStreamingLayoutConfig` when passing this preset to `startRecording()`.
</Note>

<ResponseField name="preset" type="string">
  Always `"audio-only"`.
</ResponseField>

<ResponseField name="participants" type="DailyStreamingParticipantsConfig">
  Optional. See [participants](#participants) above.
</ResponseField>

```json theme={null}
{ "preset": "audio-only" }
```

***

### raw-tracks-audio-only

Records raw audio tracks without mixing. Each participant's audio is captured as a separate track.

<ResponseField name="preset" type="string">
  Always `"raw-tracks-audio-only"`.
</ResponseField>

```json theme={null}
{ "preset": "raw-tracks-audio-only" }
```

***

### custom

Renders a custom composition using Daily's compositor. Requires a `composition_id` when starting a stream or recording; `composition_id` cannot be changed mid-session via an update call.

<ResponseField name="preset" type="string">
  Always `"custom"`.
</ResponseField>

<ResponseField name="composition_id" type="string">
  The ID of the custom composition to use. Required when starting — cannot be changed on update calls.
</ResponseField>

<ResponseField name="composition_params" type="object">
  Optional. Key/value pairs passed to the composition as parameters. Values must be `boolean`, `number`, or `string`. Can be updated mid-session via `updateRecording()` or `updateLiveStreaming()`.
</ResponseField>

<ResponseField name="session_assets" type="object">
  Optional. Key/value pairs mapping asset names to URLs, made available to the composition. Only valid when starting — cannot be set on update calls.
</ResponseField>

<ResponseField name="participants" type="DailyStreamingParticipantsConfig">
  Optional. See [participants](#participants) above.
</ResponseField>

```json theme={null}
// Starting a custom composition
{
  "preset": "custom",
  "composition_id": "my-composition",
  "composition_params": {
    "showLowerThirds": true,
    "accentColor": "#ff0000"
  },
  "session_assets": {
    "logo": "https://example.com/logo.png"
  }
}
```

```json theme={null}
// Updating composition params mid-session
{
  "preset": "custom",
  "composition_params": {
    "showLowerThirds": false
  }
}
```

***

## VCS baseline composition

<Badge color="blue">Paid plan only</Badge>

When using `preset: 'custom'`, you can set `composition_id` to `'daily:baseline'` to use Daily's built-in VCS baseline compositor. The `composition_params` object then accepts the following properties to control layouts, overlays, and other visual elements.

<VCSInstanceMethodDesc vcsType="live-streaming" />

### Baseline composition properties

<ParamField body="mode" type="string" default="grid">
  Sets the layout mode. Valid options:

  * **single**: Show a single full-screen video.
  * **split**: Show the first two participants side-by-side.
  * **grid**: Show up to 20 videos in a grid layout.
  * **dominant**: Show the active speaker in a large pane on the left, with additional video thumbnails on the right.
  * **pip**: Show the active speaker in a full-screen view, with the first participant inlaid in a corner.
</ParamField>

<ParamField body="showTextOverlay" type="boolean" default="false">
  Sets whether a text overlay is displayed. You can configure the contents of the overlay with the `text.*` properties.
</ParamField>

<ParamField body="showImageOverlay" type="boolean" default="false">
  Sets whether an image overlay is displayed. You can configure the display of the overlay with the `image.*` properties. The image used must be passed in the `session_id` layout option when the stream or recording is *started*.
</ParamField>

<ParamField body="showBannerOverlay" type="boolean" default="false">
  Sets whether a banner overlay is displayed. The banner can be used for TV-style "lower third" graphics, or displayed in any corner. You can configure the content of the overlay with the `banner.*` properties.
</ParamField>

<ParamField body="showWebFrameOverlay" type="boolean" default="false">
  Sets whether a WebFrame overlay is displayed. You can configure the display of this live web browser overlay with the `webFrame.*` properties. The URL and the browser viewport size can be changed while your stream or recording is running.
</ParamField>

<ParamField body="showSidebar" type="boolean" default="false">
  Sets whether a sidebar is displayed. You can configure the display of the sidebar with the `sidebar.*` properties.
</ParamField>

<ParamField body="showTitleSlate" type="boolean" default="false">
  Sets whether a title screen (a "slate") is displayed. You can configure the display of the slate with the `titleSlate.*` properties.
</ParamField>

<ParamField body="enableAutoOpeningSlate" type="boolean" default="false">
  Sets whether a title screen (a "slate") is automatically shown at the start of the stream. You can configure the display of this automatic slate with the `openingSlate.` properties.
</ParamField>

<ParamField body="videoSettings.maxCamStreams" type="number" default="25">
  Limits the number of non-screenshare streams that are included in the output.
</ParamField>

<ParamField body="videoSettings.preferredParticipantIds" type="string" default="">
  Lets you do render-time reordering of video inputs according to participant IDs within a Daily room. To enable this sorting, pass a comma-separated list of participant IDs as the value for this param; video inputs matching these IDs will be moved to the top of the list. If you pass an ID that is not present in the room, it's ignored. All other video inputs will remain in their original order. The default value is an empty string indicating no reordering. Also note that `videoSettings.preferScreenshare` takes precedence over the ordering passed here. For more information about how participants and videos are sorted, see the section on [selecting participants](#selecting-participants).
</ParamField>

<ParamField body="videoSettings.preferScreenshare" type="boolean" default="false">
  When enabled, screen share inputs will be sorted before camera inputs. This is useful when prioritizing screen shares in your layout, especially when all inputs are not included in the final stream. For more information about how participants and videos are sorted, see the section on [selecting participants](#selecting-participants).
</ParamField>

<ParamField body="videoSettings.omitPausedVideo" type="boolean" default="false">
  When enabled, paused video inputs will not be included. By default this is off, and paused inputs are displayed with a placeholder graphic. ("Paused video" means that the video track for a participant is not available, either due to user action or network conditions.)
</ParamField>

<ParamField body="videoSettings.omitAudioOnly" type="boolean" default="false">
  When enabled, audio-only inputs will not be included in rendering. By default this is off, and audio participants are displayed with a placeholder graphic.
</ParamField>

<ParamField body="videoSettings.omitExtraScreenshares" type="boolean" default="false">
  When enabled, any screenshare video inputs beyond the first one will not be included in rendering. You can control the ordering of the inputs using the `layout.participants` property to explicitly select which participant should be first in the list of inputs.
</ParamField>

<ParamField body="videoSettings.showParticipantLabels" type="boolean" default="false">
  Sets whether call participants' names are displayed on their video tiles.
</ParamField>

<ParamField body="videoSettings.roundedCorners" type="boolean" default="false">
  Sets whether to display video tiles with squared or rounded corners. Note that some modes (`dominant` and `pip`) have additional params to control whether the main video has rounded corners or not.
</ParamField>

<ParamField body="videoSettings.cornerRadius_gu" type="number" default="1.2">
  Sets the corner radius applied to video layers when `videoSettings.roundedCorners` is enabled, in grid units.
</ParamField>

<ParamField body="videoSettings.scaleMode" type="string" default="fill">
  Controls how source video is displayed inside a tile if they have different aspect ratios. Use `'fill'` to crop the video to fill the entire tile. Use `'fit'` to make sure the entire video fits inside the tile, adding letterboxes or pillarboxes as necessary.
</ParamField>

<ParamField body="videoSettings.scaleModeForScreenshare" type="string" default="fit">
  Controls how a screenshare video is displayed inside a tile if they have different aspect ratios. Use `'fill'` to crop the video to fill the entire tile. Use `'fit'` to make sure the entire video fits inside the tile, adding letterboxes or pillarboxes as necessary.
</ParamField>

<ParamField body="videoSettings.placeholder.bgColor" type="string" default="rgb(0, 50, 80)">
  Sets the background color for video placeholder tile. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="videoSettings.highlight.color" type="string" default="rgb(255, 255, 255)">
  Sets the highlight color. It's used as the border color to indicate the 'dominant' video input (typically the active speaker). Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="videoSettings.highlight.stroke_gu" type="number" default="0.2">
  Sets the stroke width used to render a highlight border. See also `'videoSettings.highlight.color'`. Specified in grid units.
</ParamField>

<ParamField body="videoSettings.split.margin_gu" type="number" default="0">
  Sets the visual margin between the two video layers shown in `split` mode, in grid units.
</ParamField>

<ParamField body="videoSettings.split.direction" type="string" default="auto-by-viewport">
  Selects whether the `'split'` layout mode is rendered in a horizontal or vertical configuration. The default value `'auto-by-viewport'` means that the split direction will be automatically selected to be most appropriate for the current viewport size: if the viewport is landscape or square, the split axis is vertical; if portrait, the split axis is horizontal. Valid options: `'auto-by-viewport', 'vertical', 'horizontal'`
</ParamField>

<ParamField body="videoSettings.split.scaleModeOverrides" type="string" default="">
  Overrides the scaleMode setting for the `split` layout mode. Both sides of the split can have separately defined scale modes. Pass a comma-separated list such as `fill, fit` (this would set the left-hand side video to `fill` and the right-hand side video to `fit`). See documentation for the `videoSettings.scaleMode` parameter for the valid options. Note that this setting also overrides `videoSettings.scaleModeForScreenshare`.
</ParamField>

<ParamField body="videoSettings.grid.useDominantForSharing" type="boolean" default="false">
  When enabled, the layout will automatically switch to `dominant` mode from `grid` if a screenshare video input is available. By using this automatic behavior, you avoid having to manually switch the mode via an API call.
</ParamField>

<ParamField body="videoSettings.grid.itemInterval_gu" type="number" default="-1">
  Overrides the visual margin between items in `grid` mode, in grid units. The default value of -1 means that the layout algorithm selects a reasonable margin automatically depending on the number of videos.
</ParamField>

<ParamField body="videoSettings.grid.outerPadding_gu" type="number" default="-1">
  Overrides the outer padding around items in `grid` mode, in grid units. The default value of -1 means that the layout algorithm selects a reasonable padding automatically depending on the number of videos.
</ParamField>

<ParamField body="videoSettings.grid.highlightDominant" type="boolean" default="true">
  By default, the `grid` mode will highlight the dominant video (typically the "active speaker") with a light outline. You can disable the highlight using this setting.
</ParamField>

<ParamField body="videoSettings.grid.preserveAspectRatio" type="boolean" default="true">
  By default, the layout for the `grid` mode will try to preserve the aspect ratio of the input videos, i.e. avoid cropping the videos and instead add margins around the grid if needed. Setting this parameter to `false` will make the grid layout fill all available area, potentially cropping the videos.
</ParamField>

<ParamField body="videoSettings.dominant.position" type="string" default="left">
  Control where the dominant (or "active speaker") video is displayed in the `dominant` layout mode. Values are `left`, `right`, `top` or `bottom`.
</ParamField>

<ParamField body="videoSettings.dominant.splitPos" type="number" default="0.8">
  Sets the position of the imaginary line separating the dominant video from the smaller tiles when using the `dominant` layout. Values are from 0 to 1. The default is 0.8, so if `videoSettings.dominant.position` is set to `left`, the dominant video will take 80% of the width of the screen on the left.
</ParamField>

<ParamField body="videoSettings.dominant.numChiclets" type="number" default="5">
  Controls how many "chiclets", or smaller video tiles, appear alongside the dominant video when using the `dominant` layout.
</ParamField>

<ParamField body="videoSettings.dominant.followDomFlag" type="boolean" default="true">
  When in `dominant` mode, the large tile displays the active speaker by default. Turn off this `followDomFlag` to display the first participant instead of the active speaker.
</ParamField>

<ParamField body="videoSettings.dominant.itemInterval_gu" type="number" default="0.7">
  Margin between the “chiclet” items, in grid units.
</ParamField>

<ParamField body="videoSettings.dominant.outerPadding_gu" type="number" default="0.5">
  Padding around the row/column of “chiclet” items, in grid units.
</ParamField>

<ParamField body="videoSettings.dominant.splitMargin_gu" type="number" default="0">
  Margin between the "dominant" video and the row/column of "chiclet" items, in grid units.
</ParamField>

<ParamField body="videoSettings.dominant.sharpCornersOnMain" type="boolean" default="true">
  Sets whether the "dominant" video will be rendered with rounded corners when `videoSettings.roundedCorners` is enabled. Defaults to false because sharp corners are a more natural choice for the default configuration where the dominant video is tightly aligned to viewport edges.
</ParamField>

<ParamField body="videoSettings.pip.position" type="string" default="top-right">
  Sets the position of the smaller video in the `pip` (picture-in-picture) layout. Valid options: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`.
</ParamField>

<ParamField body="videoSettings.pip.aspectRatio" type="number" default="1">
  Sets the aspect ratio of the smaller video in the `pip` layout. The default is 1.0, which produces a square video.
</ParamField>

<ParamField body="videoSettings.pip.height_gu" type="number" default="12">
  Sets the height of the smaller video in the `pip` layout, measured in grid units.
</ParamField>

<ParamField body="videoSettings.pip.margin_gu" type="number" default="1.5">
  Sets the margin between the smaller video and the edge of the frame in the `pip` layout, in grid units.
</ParamField>

<ParamField body="videoSettings.pip.followDomFlag" type="boolean" default="false">
  When in "pip" (or picture-in-picture) mode, the overlay tile displays the first participant in the participant array by default. Turn on this `followDomFlag` to display the active speaker instead.
</ParamField>

<ParamField body="videoSettings.pip.sharpCornersOnMain" type="boolean" default="true">
  Sets whether the main video in `pip` mode will be rendered with rounded corners when `videoSettings.roundedCorners` is enabled. Defaults to false because sharp corners are a more natural choice for the default configuration where the main video is full-screen (no margin to viewport edges).
</ParamField>

<ParamField body="videoSettings.labels.fontFamily" type="string" default="Roboto">
  Sets the participant label style option: font family. Valid options: `DMSans`, `Roboto`, `RobotoCondensed`, `Bitter`, `Exo`, `Magra`, `SuezOne`, `Teko`
</ParamField>

<ParamField body="videoSettings.labels.fontWeight" type="string" default="600">
  Sets the participant label text font weight. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="videoSettings.labels.fontSize_pct" type="number" default="100">
  Sets the participant label text font size.
</ParamField>

<ParamField body="videoSettings.labels.offset_x_gu" type="number" default="0">
  Sets the offset value for participant labels on the x-axis, measured in grid units.
</ParamField>

<ParamField body="videoSettings.labels.offset_y_gu" type="number" default="0">
  Sets the offset value for participant labels on the y-axis, measured in grid units.
</ParamField>

<ParamField body="videoSettings.labels.color" type="string" default="white">
  Sets the participant label font color. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="videoSettings.labels.strokeColor" type="string" default="rgba(0, 0, 0, 0.9)">
  Sets the label font stroke color (the line outlining the text letters). Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="videoSettings.margin.left_gu" type="number" default="0">
  Sets the left margin value applied to videos (in any layout mode), in grid units. You can use these `videoSettings.margin.*` params to shrink the video area, for example to make room for overlays.
</ParamField>

<ParamField body="videoSettings.margin.right_gu" type="number" default="0">
  Sets the right margin value applied to videos (in any layout mode), in grid units. You can use these `videoSettings.margin.*` params to shrink the video area, for example to make room for overlays.
</ParamField>

<ParamField body="videoSettings.margin.top_gu" type="number" default="0">
  Sets the top margin value applied to videos (in any layout mode), in grid units. You can use these `videoSettings.margin.*` params to shrink the video area, for example to make room for overlays.
</ParamField>

<ParamField body="videoSettings.margin.bottom_gu" type="number" default="0">
  Sets the bottom margin value applied to videos (in any layout mode), in grid units. You can use these `videoSettings.margin.*` params to shrink the video area, for example to make room for overlays.
</ParamField>

<ParamField body="text.content" type="string" default="">
  Sets the string to be displayed if `showTextOverlay` is true.
</ParamField>

<ParamField body="text.source" type="string" default="param">
  Sets the data source used for the text displayed in the overlay. The default value 'param' means that the value of param `text.content` is used. Valid options: `param`, `highlightLines.items`, `chatMessages`, `transcript`
</ParamField>

<ParamField body="text.align_horizontal" type="string" default="center">
  Sets the horizontal alignment of the text overlay within the video frame. Values are `left`, `right`, or `center`.
</ParamField>

<ParamField body="text.align_vertical" type="string" default="center">
  Sets the vertical alignment of the text overlay within the video frame. Values are `top`, `bottom`, or `center`.
</ParamField>

<ParamField body="text.offset_x_gu" type="number" default="0">
  Sets an x-offset (horizontal) to be applied to the text overlay's position based on the values of `text.align_horizontal` and `text.align_vertical`.
</ParamField>

<ParamField body="text.offset_y_gu" type="number" default="0">
  Sets a y-offset (vertical) to be applied to the text overlay's position based on the values of `text.align_horizontal` and `text.align_vertical`.
</ParamField>

<ParamField body="text.rotation_deg" type="number" default="0">
  Applies a rotation to the text overlay. Units are degrees, and positive is a clockwise rotation.
</ParamField>

<ParamField body="text.fontFamily" type="string" default="DMSans">
  Sets the font of the text overlay. Valid options: `DMSans`, `Roboto`, `RobotoCondensed`, `Anton`, `Bangers`, `Bitter`, `Exo`, `Magra`, `PermanentMarker`, `SuezOne`, `Teko`
</ParamField>

<ParamField body="text.fontWeight" type="string" default="500">
  Selects a weight variant from the selected font family. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="text.fontStyle" type="string" default="">
  Sets the font style for text. Valid options: 'normal','italic'.
</ParamField>

<ParamField body="text.fontSize_gu" type="number" default="2.5">
  Sets the text overlay font size using grid units (gu). By default, one grid unit is 1/36 of the smaller dimension of the viewport (e.g. 20px in a 1280\*720 stream).
</ParamField>

<ParamField body="text.color" type="string" default="rgba(255, 250, 200, 0.95)">
  Sets the color and transparency of the text overlay. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="text.strokeColor" type="string" default="rgba(0, 0, 0, 0.8)">
  Sets the color of the stroke drawn around the characters in the text overlay. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="text.stroke_gu" type="number" default="0.5">
  Sets the width of the stroke drawn around the characters in the text overlay. Specified in grid units.
</ParamField>

<ParamField body="text.highlight.color" type="text" default="rgba(255, 255, 0, 1)">
  Sets the color and transparency of a highlighted item in the text overlay. To display a highlight, the value of param `text.source` must be set to `highlightLines.items`. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="text.highlight.fontWeight" type="enum" default="700">
  Sets the font weight of a highlighted item in the text overlay. To display a highlight, the value of param `text.source` must be set to `highlightLines.items`.
</ParamField>

<ParamField body="image.assetName" type="string" default="overlay.png">
  Sets the overlay image. Icon asset must be included in `session_assets` object. `showImageOverlay` must be `true`.
</ParamField>

<ParamField body="image.emoji" type="text" default="">
  Sets an emoji to be rendered instead of an image asset. If this string is non-empty, it will override the value of `image.assetName`. The string value must be an emoji.
</ParamField>

<ParamField body="image.position" type="string" default="top-right">
  Sets position of overlay image. Valid options: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`
</ParamField>

<ParamField body="image.fullScreen" type="boolean" default="false">
  Sets overlay image to full screen.
</ParamField>

<ParamField body="image.aspectRatio" type="number" default="1.778">
  Sets aspect ratio of overlay image.
</ParamField>

<ParamField body="image.height_gu" type="number" default="12">
  Sets height of overlay image, in grid units.
</ParamField>

<ParamField body="image.margin_gu" type="number" default="1.5">
  Sets margin between the overlay image and the viewport edge, in grid units.
</ParamField>

<ParamField body="image.opacity" type="number" default="1">
  Sets opacity of overlay image, in range 0-1. Default value of 1 is full opacity.
</ParamField>

<ParamField body="image.enableFade" type="boolean" default="true">
  Sets the overlay image to fade in or out when the `showImageOverlay` property is updated.
</ParamField>

<ParamField body="webFrame.url" type="string" default="">
  Sets the web page URL to be loaded into the WebFrame overlay's embedded browser.
</ParamField>

<ParamField body="webFrame.viewportWidth_px" type="number" default="1280">
  Sets the width of the embedded browser window used to render the WebFrame overlay.
</ParamField>

<ParamField body="webFrame.viewportHeight_px" type="number" default="720">
  Sets the height of the embedded browser window used to render the WebFrame overlay.
</ParamField>

<ParamField body="webFrame.position" type="string" default="top-right">
  Sets position of the WebFrame overlay. Valid options: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`
</ParamField>

<ParamField body="webFrame.fullScreen" type="boolean" default="false">
  Sets the WebFrame overlay to full screen.
</ParamField>

<ParamField body="webFrame.height_gu" type="number" default="12">
  Sets height of the WebFrame overlay, in grid units.
</ParamField>

<ParamField body="webFrame.margin_gu" type="number" default="1.5">
  Sets margin between the WebFrame overlay and the viewport edge, in grid units.
</ParamField>

<ParamField body="webFrame.opacity" type="number" default="1">
  Sets opacity of the WebFrame overlay, in range 0-1. Default value of `1` is full opacity.
</ParamField>

<ParamField body="webFrame.enableFade" type="boolean" default="true">
  Sets the WebFrame overlay to fade in or out when the `showWebFrameOverlay` property is updated.
</ParamField>

<ParamField body="webFrame.keyPress.keyName" type="string" default="ArrowRight">
  Sets the keyboard key to be sent to the WebFrame browser in a simulated key press. Valid options:

  * Digits **0 - 9**
  * Letters **A - Z**
  * ASCII special characters, e.g. **!**, **@**, **+**, **>**, etc.
  * Function keys **F1 - F12**
  * **Enter**
  * **Escape**
  * **Backspace**
  * **Tab**
  * Arrow keys **ArrowUp, ArrowDown, ArrowLeft, ArrowRight**
  * **PageDown, PageUp**
</ParamField>

<ParamField body="webFrame.keyPress.modifiers" type="string" default="">
  Sets keyboard modifier keys to be sent to the WebFrame browser in a simulated key press. Valid options: `"Shift"`, `"Control"`, `"Alt"`, `"Meta"` (on a Mac keyboard, Alt is equal to Option and Meta is equal to Command).
</ParamField>

<ParamField body="webFrame.keyPress.key" type="number" default="0">
  Triggers a simulated key press to be sent to WebFrame. To send a key press, increment the value of `key`. (Note the difference between this and `keyName` which is the simulated key to be sent.)
</ParamField>

<ParamField body="banner.title" type="text" default="Hello world">
  Sets the title text displayed in the banner component.
</ParamField>

<ParamField body="banner.subtitle" type="text" default="This is an example subtitle">
  Sets the subtitle text displayed in the banner component.
</ParamField>

<ParamField body="banner.source" type="string" default="param">
  Sets the data source for the text displayed in the banner component. Valid options: `param`, `highlightLines.items`, `chatMessages`, `transcript`
</ParamField>

<ParamField body="banner.position" type="string">
  Sets position of the banner component. Valid options: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`
</ParamField>

<ParamField body="banner.enableTransition" type="boolean" default="true">
  Sets the banner to fade in or out when the `showBannerOverlay` property is updated.
</ParamField>

<ParamField body="banner.margin_x_gu" type="number" default="0">
  Horizontal margin, specified in grid units.
</ParamField>

<ParamField body="banner.margin_y_gu" type="number" default="1">
  Vertical margin, specified in grid units.
</ParamField>

<ParamField body="banner.padding_gu" type="number" default="2">
  Padding inside the component, specified in grid units.
</ParamField>

<ParamField body="banner.alwaysUseMaxW" type="boolean" default="false">
  Sets whether the banner component will always use its maximum width (specified using `banner.maxW_pct_default` and `banner.maxW_pct_portrait`). If false, the banner component will shrink horizontally to fit text inside it, if appropriate.
</ParamField>

<ParamField body="banner.maxW_pct_default" type="number" default="65">
  Sets the maximum width for the banner component, as a percentage of the viewport size.
</ParamField>

<ParamField body="banner.maxW_pct_portrait" type="number" default="90">
  Sets the maximum width for the banner component, as a percentage of the viewport size, applied only when the viewport aspect ratio is portrait (i.e. smaller than 1). This override is useful because on a narrow screen the banner display typically needs more horizontal space than on a landscape screen.
</ParamField>

<ParamField body="banner.rotation_deg" type="number" default="0">
  Applies a rotation to the banner component. Units are degrees, and positive is a clockwise rotation.
</ParamField>

<ParamField body="banner.cornerRadius_gu" type="number" default="0">
  Sets the corner radius of the banner component outline. Specified in grid units.
</ParamField>

<ParamField body="banner.showIcon" type="boolean" default="true">
  Sets whether an icon is displayed in the banner component (`true` or `false`).
</ParamField>

<ParamField body="banner.icon.assetName" type="text" default="">
  Sets image asset value for the banner icon. Icon asset must be included in `session_assets` object.
</ParamField>

<ParamField body="banner.icon.emoji" type="text" default="🎉">
  Sets an emoji to be rendered as the banner icon. If this string is non-empty, it will override `banner.icon.assetName`. The string value must be an emoji.
</ParamField>

<ParamField body="banner.icon.size_gu" type="number" default="3">
  Sets the size of the banner icon, specified in grid units.
</ParamField>

<ParamField body="banner.color" type="text" default="rgba(50, 60, 200, 0.9)">
  Sets the banner component's background color. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="banner.strokeColor" type="text" default="rgba(0, 0, 30, 0.44)">
  Sets the color of the outline drawn around the banner component. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="banner.stroke_gu" type="number" default="0">
  Sets the width of the stroke drawn around the banner component. Specified in grid units.
</ParamField>

<ParamField body="banner.text.color" type="text" default="white">
  Sets the banner component's text color. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="banner.text.strokeColor" type="text" default="rgba(0, 0, 0, 0.1)">
  Sets the color of the stroke drawn around the characters in the banner component. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="banner.text.stroke_gu" type="number" default="0.5">
  Sets the width of the stroke drawn around the characters in the banner component. Specified in grid units.
</ParamField>

<ParamField body="banner.text.fontFamily" type="string" default="Roboto">
  Sets the font of text displayed in the banner component. Valid options: `DMSans`, `Roboto`, `RobotoCondensed`, `Anton`, `Bangers`, `Bitter`, `Exo`, `Magra`, `PermanentMarker`, `SuezOne`, `Teko`
</ParamField>

<ParamField body="banner.title.fontSize_gu" type="number" default="2">
  Sets the banner title font size using grid units (gu). By default, one grid unit is 1/36 of the smaller dimension of the viewport (e.g. 20px in a 1280\*720 stream).
</ParamField>

<ParamField body="banner.title.fontWeight" type="string" default="500">
  Sets the banner title font weight. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="banner.title.fontStyle" type="string" default="">
  Sets the font style for the banner title. Valid options: 'normal','italic'.
</ParamField>

<ParamField body="banner.subtitle.fontSize_gu" type="number" default="1.5">
  Sets the banner subtitle font size using grid units (gu). By default, one grid unit is 1/36 of the smaller dimension of the viewport (e.g. 20px in a 1280\*720 stream).
</ParamField>

<ParamField body="banner.subtitle.fontWeight" type="string" default="300">
  Sets the banner subtitle font weight. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="banner.subtitle.fontStyle" type="string" default="">
  Sets the font style for the banner subtitle. Valid options: 'normal','italic'.
</ParamField>

<ParamField body="toast.key" type="number" default="0">
  Triggers display of toast component. To send a toast, increment the value of `key`
</ParamField>

<ParamField body="toast.text" type="string" default="Hello world">
  Sets text displayed in toast component.
</ParamField>

<ParamField body="toast.source" type="string" default="param">
  Sets the data source used for the text displayed in the toast component. The default value `param` means that the value of param `toast.content` is used. Valid options: `param`, `chatMessages`, `transcript`
</ParamField>

<ParamField body="toast.duration_secs" type="number" default="4">
  Sets duration of time toast component is displayed (in seconds).
</ParamField>

<ParamField body="toast.maxW_pct_default" type="number" default="50">
  Sets the maximum width for the toast component, as a percentage of the viewport size.
</ParamField>

<ParamField body="toast.maxW_pct_portrait" type="number" default="80">
  Sets the maximum width for the toast component, as a percentage of the viewport size, applied only when the viewport aspect ratio is portrait (i.e. smaller than 1). This override is useful because on a narrow screen the toast display typically needs more horizontal space than on a landscape screen.
</ParamField>

<ParamField body="toast.showIcon" type="boolean" default="true">
  Sets whether icon is displayed in toast component (`true` or `false`).
</ParamField>

<ParamField body="toast.icon.assetName" type="string" default="">
  Sets asset value for toast icon. Icon asset must be included in `session_assets` object.
</ParamField>

<ParamField body="toast.icon.emoji" type="text" default="🎉">
  Sets an emoji to be rendered as the toast icon. If this string is non-empty, it will override `toast.icon.assetName`. The string value must be an emoji.
</ParamField>

<ParamField body="toast.icon.size_gu" type="number" default="3">
  Sets the size of the toast icon, in grid units.
</ParamField>

<ParamField body="toast.color" type="string" default="rgba(15, 50, 110, 0.6)">
  Sets the toast component's background color. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="toast.strokeColor" type="string" default="rgba(0, 0, 30, 0.44)">
  Sets the color of the stroke drawn around the text characters in the toast component. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="toast.text.color" type="string" default="white">
  Sets the toast component's text color. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="toast.text.fontFamily" type="string" default="Roboto">
  Sets the toast component's font family. Valid options: `DMSans`, `Roboto`, `RobotoCondensed`, `Bitter`, `Exo`, `Magra`, `SuezOne`, `Teko`
</ParamField>

<ParamField body="toast.text.fontWeight" type="number" default="500">
  Sets the font weight for the toast component's text. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="toast.text.fontSize_pct" type="number" default="100">
  Sets the font size for the toast component's text.
</ParamField>

<ParamField body="openingSlate.duration_secs" type="number" default="4">
  Sets the number of seconds that the opening slate will be displayed when the stream starts. After this time, the slate goes away with a fade-out effect.
</ParamField>

<ParamField body="openingSlate.title" type="string" default="Welcome">
  Sets text displayed in the main title of the opening slate.
</ParamField>

<ParamField body="openingSlate.subtitle" type="string" default="">
  Sets text displayed in the subtitle (second line) of the opening slate.
</ParamField>

<ParamField body="openingSlate.bgImageAssetName" type="string" default="">
  Sets an image to be used as the background for the slate. This image asset must be included in `session_assets` object when starting the stream/recording.
</ParamField>

<ParamField body="openingSlate.bgColor" type="string" default="rgba(0, 0, 0, 1)">
  Sets the slate's background color. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="openingSlate.textColor" type="string" default="rgba(255, 255, 255, 1)">
  Sets the text color of the titles in the slate. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="openingSlate.fontFamily" type="string" default="Bitter">
  Sets the font of the titles in the slate. Valid options: `DMSans`, `Roboto`, `RobotoCondensed`, `Anton`, `Bangers`, `Bitter`, `Exo`, `Magra`, `PermanentMarker`, `SuezOne`, `Teko`
</ParamField>

<ParamField body="openingSlate.fontWeight" type="string" default="500">
  Selects a weight variant from the selected font family. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="openingSlate.fontStyle" type="string" default="">
  Sets the font style for the titles in the slate. Valid options: 'normal','italic'.
</ParamField>

<ParamField body="openingSlate.fontSize_gu" type="number" default="2.5">
  Sets the main title font size using grid units (gu). By default, one grid unit is 1/36 of the smaller dimension of the viewport (e.g. 20px in a 1280\*720 stream).
</ParamField>

<ParamField body="openingSlate.subtitle.fontSize_pct" type="number" default="75">
  Sets the subtitle font size as a percentage of the main title.
</ParamField>

<ParamField body="openingSlate.subtitle.fontWeight" type="string" default="400">
  Selects a weight variant from the selected font family specifically for the subtitle. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="titleSlate.enableTransition" type="boolean" default="true">
  Sets the slate to fade in or out when the `showTitleSlate` property is updated.'
</ParamField>

<ParamField body="titleSlate.title" type="string" default="Title slate">
  Sets text displayed in the main title of the slate.
</ParamField>

<ParamField body="titleSlate.subtitle" type="string" default="Subtitle">
  Sets text displayed in the subtitle (second line) of the slate.
</ParamField>

<ParamField body="titleSlate.bgImageAssetName" type="string" default="">
  Sets an image to be used as the background for the slate. This image asset must be included in `session_assets` object when starting the stream/recording.
</ParamField>

<ParamField body="titleSlate.bgColor" type="string" default="rgba(0, 0, 0, 1)">
  Sets the slate's background color. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="titleSlate.textColor" type="string" default="rgba(255, 255, 255, 1)">
  Sets the text color of the titles in the slate. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="titleSlate.fontFamily" type="string" default="Bitter">
  Sets the font of the titles in the slate. Valid options: `DMSans`, `Roboto`, `RobotoCondensed`, `Anton`, `Bangers`, `Bitter`, `Exo`, `Magra`, `PermanentMarker`, `SuezOne`, `Teko`
</ParamField>

<ParamField body="titleSlate.fontWeight" type="string" default="500">
  Selects a weight variant from the selected font family. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="titleSlate.fontStyle" type="string" default="">
  Sets the font style for the titles in the slate. Valid options: 'normal','italic'.
</ParamField>

<ParamField body="titleSlate.fontSize_gu" type="number" default="2.5">
  Sets the main title font size using grid units (gu). By default, one grid unit is 1/36 of the smaller dimension of the viewport (e.g. 20px in a 1280\*720 stream).
</ParamField>

<ParamField body="titleSlate.subtitle.fontSize_pct" type="number" default="75">
  Sets the subtitle font size as a percentage of the main title.
</ParamField>

<ParamField body="titleSlate.subtitle.fontWeight" type="string" default="400">
  Selects a weight variant from the selected font family specifically for the subtitle. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="sidebar.shrinkVideoLayout" type="boolean" default="false">
  Sets whether the sidebar is displayed on top of video elements. If set to `true` , the video layout is shrunk horizontally to make room for the sidebar so they don't overlap.
</ParamField>

<ParamField body="sidebar.source" type="string" default="highlightLines.items">
  Sets the data source for the text displayed in the sidebar. Valid options: `param`, `highlightLines.items`, `chatMessages`, `transcript`
</ParamField>

<ParamField body="sidebar.padding_gu" type="number" default="1.5">
  Padding inside the sidebar, specified in grid units.
</ParamField>

<ParamField body="sidebar.width_pct_landscape" type="number" default="30">
  Sets the width of the sidebar, as a percentage of the viewport size, applied when the viewport is landscape (its aspect ratio is greater than 1).
</ParamField>

<ParamField body="sidebar.height_pct_portrait" type="number" default="25">
  Sets the width of the sidebar, as a percentage of the viewport size, applied when the viewport is portrait or square (its aspect ratio is less than or equal to 1).
</ParamField>

<ParamField body="sidebar.bgColor" type="text" default="rgba(0, 0, 50, 0.55)">
  Sets the sidebar's background color and opacity. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="sidebar.textColor" type="text" default="rgba(255, 255, 255, 0.94)">
  Sets the sidebar's text color and opacity. Valid options:

  * Hex color codes
  * RGB or RGBA syntax
  * Standard CSS color names (e.g. 'blue')
</ParamField>

<ParamField body="sidebar.fontFamily" type="string" default="DMSans">
  Sets the font of text displayed in the sidebar. Valid options: `DMSans`, `Roboto`, `RobotoCondensed`, `Anton`, `Bangers`, `Bitter`, `Exo`, `Magra`, `PermanentMarker`, `SuezOne`, `Teko`
</ParamField>

<ParamField body="sidebar.fontWeight" type="string" default="300">
  Sets the sidebar text font weight. Valid options: `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`.

  Note: Not all font weights are valid for every font family.
</ParamField>

<ParamField body="sidebar.fontStyle" type="string" default="">
  Sets the font style for text in the sidebar. Valid options: 'normal','italic'.
</ParamField>

<ParamField body="sidebar.fontSize_gu" type="number" default="1.4">
  Sets the sidebar text font size using grid units (gu). By default, one grid unit is 1/36 of the smaller dimension of the viewport (e.g. 20px in a 1280\*720 stream).
</ParamField>

<ParamField body="sidebar.textHighlight.color" type="text" default="rgba(255, 230, 0, 1)">
  Sets the color used for the highlighted item in the sidebar.
</ParamField>

<ParamField body="sidebar.textHighlight.fontWeight" type="string" default="600">
  Sets the font weight used for the highlighted item in the sidebar.
</ParamField>

<ParamField body="highlightLines.items" type="text">
  Sets a list of text items. Items must be separated by newline characters. This param is a data source that can be displayed in other components like TextOverlay, Banner and Sidebar using the various "source" params available in the settings for those components.
</ParamField>

<ParamField body="highlightLines.position" type="number" default="0">
  Sets the highlight index associated with the text items specified in `highlightLines.items`. The item at this index will be displayed using a special highlight style (which depends on the component used to display this data). If you don't want a highlight, set this value to -1.
</ParamField>

<ParamField body="emojiReactions.source" type="string" default="emojiReactions">
  Sets the data source used for emoji reactions. The default value `emojiReactions` means that this component will display emojis that are sent via the standard source API.

  The other valid option is `param`, which lets you send a reaction using param values instead of the standard source. The steps are as follows: set `emojiReactions.source` to `param`, set a single-emoji string for `emojiReactions.emoji`, and increment the value of `emojiReactions.key` to send one emoji for display.
</ParamField>

<ParamField body="emojiReactions.key" type="number" default="0">
  If `emojiReactions.source` is set to `param`, increment this numeric key to send a new emoji for display.
</ParamField>

<ParamField body="emojiReactions.emoji" type="text" default="">
  If `emojiReactions.source` is set to `param`, set a single emoji as the string value for this param, and it will be the next emoji reaction rendered when `emojiReactions.key` is incremented.
</ParamField>

<ParamField body="emojiReactions.offset_x_gu" type="number" default="0">
  Sets a horizontal offset applied to the emoji reactions animation rendering (each new emoji floats up from the bottom of the screen). Specified in grid units.
</ParamField>

<ParamField body="debug.showRoomState" type="boolean" default="false">
  When set to true, a room state debugging display is visible. It prints various information about participant state.
</ParamField>

<ParamField body="debug.overlayOpacity" type="number" default="90">
  Sets the opacity of the debugging display which can be toggled using `debug.showRoomState`.
</ParamField>

## Selecting participants

The baseline composition has several modes that display multiple participant videos. You may be wondering how to control which participants appear in specific places within those layouts.

Internally, VCS uses an ordered array of video inputs that it calls ["video input slots"](/docs/vcs/components/video). By default, that array will contain all participants in the order in which they joined the call. But there are two ways you can override this default behavior and choose which participants appear in your layout:

1. Participant selection on the **room level** using the `participants` property.
2. Input reordering on the **composition level** (a.k.a. switching) using the [`preferredParticipantIds`](#param-video-settings-preferred-participant-ids) and [`preferScreenshare`](#param-video-settings-prefer-screenshare) params available in the baseline composition.

These two are not mutually exclusive. What's the difference, and when should you use one or the other?

**Room-level participant selection** is a powerful generic tool. It lets you choose any participants within the room, and will trigger any necessary backend connections so that a participant's audio and video streams become available to the VCS rendering server. This means there may be a slight delay as connections are made.

In contrast, **composition-level input reordering** (a.k.a. switching) happens at the very last moment in the VCS engine just before a video frame is rendered. (The name "switching" refers to a video switcher, a hardware device used in traditional video production for this kind of input control.) It's applied together with any other composition param updates you're sending, so there is a guarantee of synchronization. You should use this method when you want to ensure that the reordering of inputs happens precisely at the same time as your update to some other composition param value(s). For example, if you're switching a layout mode and want the inputs to be sorted in a different way simultaneously.

You can use the two methods together. Room-level selection using the `participants` property lets you establish the participants whose streams will be available to the rendering. You can then do rapid switching within that selection using the [`preferredParticipantIds`](#param-video-settings-preferred-participant-ids) and [`preferScreenshare`](#param-video-settings-prefer-screenshare) params in the baseline composition.

Here's an example of selecting three specific participant video tracks, everyone's audio tracks, and sorting the video by most recent active speaker:

```javascript theme={null}
{
	layout: {
		preset: "custom",
		composition_params: {...},
		participants: {
			video: ["participant-guid-1", "participant-guid-2", "participant-guid-3"],
			audio: ["*"],
			sort: "active"
		}
	}
}
```

Here's another example where we're further sorting the same video tracks using the baseline composition params. The params update is switching to a different layout mode (`'split'`). This mode can only show two participants, so we use `videoSettings.preferredParticipantIds` to select the two participants in a clean frame-synchronized way, without having to modify the underlying connections made via the `participants` property:

```javascript theme={null}
{
	layout: {
		preset: "custom",
		composition_params: {
			mode: 'split',
			'videoSettings.preferredParticipantIds': 'participant-guid-2, participant-guid-1',
		},
		participants: {
			video: ["participant-guid-1", "participant-guid-2", "participant-guid-3"],
			audio: ["*"],
			sort: "active"
		}
	}
}
```

<Warning>
  **If you include the `participants` object in a `startLiveStreaming()`/`startRecording()` or `updateLiveStreaming()`/`updateRecording()` call, you need to include it in any subsequent `updateLiveStreaming()`/`updateRecording()` calls as well, even if you aren't changing it.**

  If you set the `participants` property for your recording or live stream and then make an `updateLiveStreaming()`/`updateRecording()` call to update the `composition_params`, you'll need to resend the same values you used before in the `participants` property. This is true even if you are not updating the `participants` property. If you don't, the participant configuration will reset to default, as if you hadn't set it in the first place —meaning VCS will receive all audio and video tracks from all participants, sorted by the order in which the participants joined the call.
</Warning>

### `participants` properties

<ParamField body="video" type="array">
  Required. An array of strings indicating which participant videos to make available to VCS. Possible values are:

  * `["participant-guid-1", "participant-guid-2", "participant-guid-3"]`: A list of specific participant IDs

  * `["*"]`: everyone

  * `["owners"]`: All call owners
</ParamField>

<ParamField body="audio" type="array">
  An optional array of strings indicating which participant audio tracks to make available to VCS. Possible values are the same as the `video` property.
</ParamField>

<ParamField body="sort" type="string">
  The only currently valid value for this property is `"active"`. This property controls the order in which VCS sees the participant video tracks. When set to `"active"`, each time the call's active speaker changes to a different participant, that participant will bubble up to the first position in the array. In other words, setting sort to `"active"` will cause an n-tile layout to always show the n most recent speakers in the call. If you leave the property unset, the list of participants will stay in a fixed order: either the order you specified in the `video` property, or in the order they joined the call if you use `"*"` or `"owners"`.
</ParamField>

## Session assets

Session assets — images or custom VCS components — that can be passed as assets and used during a live stream or cloud recording. To learn more, visit our [Session assets page](/docs/vcs/session-assets) in the VCS SDK reference docs.

**Note**: Session assets must be made available at the beginning of the recording or live stream even if they are not used until later in the call.

```javascript theme={null}
await call.startLiveStreaming({
  instanceId: '00000000-0000-4000-8000-000000000000', // optional: default value
  rtmpUrl: 'RTMP_URL',
  width: 1280,
  height: 720,
  layout: {
    preset: 'custom', // required
    composition_id: 'daily:baseline', // optional: default value
    composition_params: {
      // ... Add your composition params here
    },
    session_assets: {
      // the key can be any string
      // the value must be an absolute URL to a hosted asset
      'images/logo': 'https://example.com/foobar.png',
    },
  },
});
```

## Default values

### Composition parameter defaults

## See also

<CardGroup>
  <Card title="Types" icon="t" iconType="solid">
    * [DailyStreamingOptions](/reference/react-native/types/daily-streaming-options)
  </Card>

  <Card title="Methods" icon="code" iconType="solid">
    * [startRecording()](/reference/react-native/instance-methods/start-recording)
    * [updateRecording()](/reference/react-native/instance-methods/update-recording)
    * [startLiveStreaming()](/reference/react-native/instance-methods/start-live-streaming)
    * [updateLiveStreaming()](/reference/react-native/instance-methods/update-live-streaming)
  </Card>

  <Card title="Events" icon="bolt" iconType="solid">
    * [Recording events](/reference/react-native/events/recording-events)
    * [Live streaming events](/reference/react-native/events/live-streaming-events)
  </Card>
</CardGroup>
