startScreenShare() accepts one of two argument shapes — or no arguments at all:
- Let Daily handle capture (
DailyStartScreenShare) — Daily callsgetDisplayMedia()for you, optionally using constraints and quality settings you provide. This is the recommended option for most use cases. - Bring your own stream (
DailyStartScreenShareFromStream) — you callgetDisplayMedia()yourself (or source a stream from Electron’sdesktopCapturer, a canvas, etc.) and hand the resultingMediaStreamto Daily.
call.stopScreenShare().
startScreenShare() is non-blocking — the browser’s native picker opens asynchronously. Listen for the events below to know when sharing actually begins or is canceled.
Let Daily handle capture
Recommended CallstartScreenShare() with no arguments to use Daily’s defaults, or pass a DailyStartScreenShare object to configure the capture:
Options forwarded directly to
navigator.mediaDevices.getDisplayMedia(). Use
these to request system audio, control surface switching, and more.Controls the video encoding quality for the shared screen. Accepts either a
preset string or a custom
DailyVideoSendSettings object. See below for details.DailyDisplayMediaStreamOptions
Request system audio in the screen share. Default is browser-dependent.
Video constraints for the captured surface.
Whether to include the current browser tab as a selectable source.
Whether to show an in-call surface-switching control (Chrome 107+).
Whether to offer system audio capture in the picker (Windows/Chrome only).
Bring your own stream
If you already have aMediaStream — captured with your own getDisplayMedia() call, sourced from an Electron desktopCapturer, or otherwise constructed — pass it via DailyStartScreenShareFromStream. Daily will not call getDisplayMedia() in this case.
A
MediaStream whose first video track (and optionally first audio track)
will be used as the screen share source.Optional quality preset or custom settings for the provided video track. See below.
Screenshare streams vs. custom tracks
If you have aMediaStream you want to send, you have two options: pass it to startScreenShare({ mediaStream: stream }) or send it as a custom track via startCustomTrack(). These are not interchangeable — Daily treats screen share video tracks differently from other video tracks, and routing a stream through the wrong path will cause incorrect behavior.
In Chromium-based browsers, a screen share video track becomes muted at the browser level whenever its content is not changing — for example, when a shared document is idle. This is normal browser behavior and does not mean the user stopped sharing or there are issues with the track. To avoid incorrectly firing track-stopped or transitioning to an interrupted state, Daily suppresses the muted signal on screen share video tracks. This suppression only applies to tracks sent via startScreenShare().
Use startScreenShare({ mediaStream: stream }) when your stream is screen content — a getDisplayMedia() capture, an Electron desktopCapturer stream, or any source that may go idle between updates. The muted-suppression handling will prevent spurious interruptions.
Use startCustomTrack() when your stream is not screen content — a canvas animation, a virtual camera, or any source that should respond normally to the muted signal. Routing this through startScreenShare() would mask legitimate track state changes.
Send Settings
Both methods of screensharing allow you to define the quality of the sending stream by either providing a preset or passing a customDailyVideoSendSettings object. DailyScreenVideoSendSettingsPreset provides four named presets optimized for different content types:
| Preset | Best for |
|---|---|
'default-screen-video' | General purpose (Daily’s default) |
'detail-optimized' | Text-heavy content — slides, IDEs, documents |
'motion-optimized' | Video playback, animations, fast UI |
'motion-and-detail-balanced' | Mixed content such as interactive demos |
DailyVideoSendSettings object:
Updating screen share state mid-share
UseupdateScreenShare() to enable or disable the screen video or audio tracks after sharing has started — without stopping and restarting the entire screen share:
Reading local screen share state
Events
local-screen-share-started
Fired when the local participant’s screen share begins. Useful for updating UI to show a “stop sharing” button.
local-screen-share-stopped
Fired when screen sharing ends — either because your code called stopScreenShare() or because the user clicked the browser’s built-in “Stop sharing” button.
local-screen-share-canceled
Fired when the user opens the browser picker but then dismisses it without selecting a source.
Detecting remote screen shares
Remote screen share tracks arrive via the standardtrack-started / track-stopped events with type === 'screenVideo' or type === 'screenAudio':