diff --git a/site/src/content/docs/concepts/accessibility.mdx b/site/src/content/docs/concepts/accessibility.mdx
index 745bf0c6..0ad60a6a 100644
--- a/site/src/content/docs/concepts/accessibility.mdx
+++ b/site/src/content/docs/concepts/accessibility.mdx
@@ -30,6 +30,14 @@ All interactive components support keyboard control. For example, buttons activa
Interactive elements are focusable when enabled and leave the [tab order](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) when disabled. Popover triggers link to their popups with `aria-controls` and `aria-expanded`.
+The player container is focusable and labeled: it takes `role="group"`, `tabindex="0"`, and an `aria-label` you can override. Keyboard users can tab to the player as a whole, and screen readers announce it as a named group.
+
+## Status announcements
+
+The player announces confirmed state changes through a visually hidden live region (`role="status"`), so screen reader users hear when playback starts or pauses, captions turn on or off, fullscreen, picture-in-picture, playback rate, or volume change, and where a seek lands.
+
+Announcements follow confirmed state from the player store rather than requested changes, so routine time updates never reach the live region. Rapid volume and seek changes are grouped into a single announcement, and the player stays quiet while one of its sliders has focus, since the slider already announces its own value. State the store tracks is covered for you; a custom control that tracks its own state needs its own live region.
+
## Captions and subtitles
The text tracks feature supports captions and subtitles. Closed captions in the U.S. are governed by the [FCC](https://www.fcc.gov/) under the [CVAA](https://www.fcc.gov/consumers/guides/21st-century-communications-and-video-accessibility-act-cvaa), which requires both captioning and viewer control over caption appearance (font, size, color, opacity, and edge style). Non-compliance carries legal risk. The [WebKit Caption Display Settings explainer](https://github.com/WebKit/explainers/tree/main/CaptionDisplaySettings) tracks how browsers are bringing these customization preferences into the web platform natively.
diff --git a/site/src/content/docs/concepts/cast.mdx b/site/src/content/docs/concepts/cast.mdx
index 9b6ccf70..fe194366 100644
--- a/site/src/content/docs/concepts/cast.mdx
+++ b/site/src/content/docs/concepts/cast.mdx
@@ -73,8 +73,8 @@ Cast only works in Chromium-based browsers (Chrome, Edge, and others built on Bl
Cast uses a **sender / receiver** model:
-- **Sender** — the browser tab. It sends the receiver a load request with the source URL and metadata, then issues playback commands (play, pause, seek, volume).
-- **Receiver** — the Chromecast device running a receiver application: Google's default media receiver, or a custom one you configure.
+- **Sender**: the browser tab. It sends the receiver a load request with the source URL and metadata, then issues playback commands (play, pause, seek, volume).
+- **Receiver**: the Chromecast device running a receiver application, either Google's default media receiver or a custom one you configure.
### Session lifecycle
@@ -86,7 +86,7 @@ A Cast session moves through three states, exposed by the
-Pass Cast options as props of the `GoogleCast` component.
-
-
-
-Set Cast options as attributes on the `` element. Object-valued options (like `customData`) are properties only.
-
-
-### Custom receiver application ID
-
-By default, Video.js casts to Google's [Default Media Receiver](https://developers.google.com/cast/docs/web_sender/integrate#default_media_web_receiver) (`CC1AD845`). To use your own receiver app, set `receiver`:
-
-
-```tsx
-
- // [!code focus]
-```
-
-
-
-```html
-
-
-```
-
-
-### Custom data on load
-
-Send extra data (auth tokens, user IDs) to the receiver with each load request via `customData`. The receiver app reads it from the load request's `customData` field:
-
-
-```tsx
-
- // [!code focus]
-```
-
-
-
-```ts
-const googleCast = document.querySelector('google-cast');
-googleCast.customData = { token: 'abc123', userId: 'u_789' }; // [!code focus]
-```
-
-
-### Cast a different source
-
-By default the receiver loads the same URL the browser plays. Set `src` (and optionally `contentType`) to send the receiver a different one — for example, cast an HLS stream while the browser plays an MP4:
+By default, the receiver loads the same source the browser plays through Google's [Default Media Receiver](https://developers.google.com/cast/docs/web_sender/integrate#default_media_web_receiver). Point Cast at your own receiver app, send a different source, attach custom data to the load request, or override the stream type through the component's options:
```tsx
@@ -170,31 +125,14 @@ By default the receiver loads the same URL the browser plays. Set `src` (and opt
```html
```
-### HLS on the receiver
-
-When the Cast source is an HLS playlist, Video.js inspects the playlist, detects the segment format (TS or fMP4), and sets `hlsSegmentFormat` / `hlsVideoSegmentFormat` on the Cast load request. The default media receiver plays HLS natively; no extra configuration needed.
-
-Set `streamType` to tell the receiver whether the stream is `'on-demand'` or `'live'`. When unset, it falls back to the player's `streamType`:
-
-
-```tsx
-
- // [!code focus]
-```
-
-
-
-```html
-
-
-```
-
+The GoogleCast reference documents every option. HLS sources need no extra receiver setup: Video.js detects the segment format and configures the load request, and the Default Media Receiver plays HLS natively.
## Read Cast state
@@ -225,40 +163,10 @@ class CastStatus extends HTMLElement {
## Browser availability
-The Remote Playback feature reports availability as `'available'` (a device is on the network), `'unavailable'` (no device found), or `'unsupported'` (the browser can't cast). The `CastButton` keeps this raw value in `data-availability`, but handles presentation for you:
-
-- When Cast is unsupported, the HTML custom element receives the native `hidden` attribute and the React component returns `null`.
-- When Cast is supported but no device is reachable, the button remains visible with `aria-disabled="true"` and `data-disabled`.
-
-Use `data-disabled` to style the visible, non-interactive state:
-
-
-```css
-media-cast-button[data-disabled] {
- cursor: not-allowed;
- opacity: 0.5;
-}
-```
-
-
-
-`CastButton` renders a `
-
-Unsupported buttons hide automatically, so no availability selector or extra hiding CSS is required.
+The Remote Playback feature reports availability as `'available'` (a device is on the network), `'unavailable'` (no device found), or `'unsupported'` (the browser can't cast). A CastButton handles the presentation for you: it hides itself when Cast is unsupported, and shows a disabled state when Cast is supported but no device is reachable. See its reference for the data attributes and styling hooks.
## See also
+GoogleCast referenceCastButton component referenceRemote Playback feature reference
diff --git a/site/src/content/docs/concepts/mux-data.mdx b/site/src/content/docs/concepts/mux-data.mdx
index c4a99049..6f6f343b 100644
--- a/site/src/content/docs/concepts/mux-data.mdx
+++ b/site/src/content/docs/concepts/mux-data.mdx
@@ -8,7 +8,7 @@ import DocsLink from '@/components/docs/DocsLink.astro';
import DocsLinkCard from '@/components/docs/DocsLinkCard.astro';
import Aside from '@/components/Aside.astro';
-[Mux Data](https://www.mux.com/data) measures playback quality — startup time, rebuffering, playback failures, and watch time. Add the Mux Data component to a player and it monitors whichever media that player is playing:
+[Mux Data](https://www.mux.com/data) measures playback quality: startup time, rebuffering, playback failures, and watch time. Add the Mux Data component to a player and it monitors whichever media that player is playing:
```tsx title="App.tsx"
@@ -55,7 +55,7 @@ Mux Data is opt-in. No media element monitors playback on its own, Mux ones incl
Mux Data needs to know which environment a view belongs to. For Mux-hosted playback it works that out on its own: the component reports the Mux playback ID as the view's `video_id`, and Mux attributes the view to the environment that owns that playback ID.
-Set `envKey` when you monitor a source Mux doesn't host — a self-hosted HLS or DASH stream, for example. Find the key in the [Mux dashboard](https://dashboard.mux.com/settings/data):
+Set `envKey` when you monitor a source Mux doesn't host, like a self-hosted HLS or DASH stream. Find the key in the [Mux dashboard](https://dashboard.mux.com/settings/data):
```tsx
@@ -96,40 +96,13 @@ muxData.metadata = { video_title: 'Big Buck Bunny', viewer_user_id: 'u_789' }; /
```
-## Options
+## Configuration
-
-| Prop | Type | Description |
-|---|---|---|
-| `envKey` | `string` | Mux Data environment key the beacons are sent to. Optional for Mux-hosted playback |
-| `metadata` | `object` | Mux Data metadata for the view |
-| `playerSoftwareName` | `string` | Player name reported to Mux Data |
-| `playerSoftwareVersion` | `string` | Player version reported to Mux Data. Defaults to the Video.js version |
-| `playerInitTime` | `number` | Epoch milliseconds the player was initialized. Defaults to when the component was created |
-| `beaconCollectionDomain` | `string` | Custom domain the beacons are sent to |
-| `disableCookies` | `boolean` | Stops the SDK from setting cookies |
-| `debug` | `boolean` | Turns on SDK debug logging |
-| `MuxDataSdk` | `object` | SDK used for monitoring. Set it to `undefined` to switch monitoring off |
-
-
-
-| Attribute | Property | Description |
-|---|---|---|
-| `env-key` | `envKey` | Mux Data environment key the beacons are sent to. Optional for Mux-hosted playback |
-| — | `metadata` | Mux Data metadata for the view |
-| `player-software-name` | `playerSoftwareName` | Player name reported to Mux Data |
-| `player-software-version` | `playerSoftwareVersion` | Player version reported to Mux Data. Defaults to the Video.js version |
-| `player-init-time` | `playerInitTime` | Epoch milliseconds the player was initialized. Defaults to when the element was created |
-| `beacon-collection-domain` | `beaconCollectionDomain` | Custom domain the beacons are sent to |
-| `disable-cookies` | `disableCookies` | Stops the SDK from setting cookies |
-| `debug` | `debug` | Turns on SDK debug logging |
-| — | `MuxDataSdk` | SDK used for monitoring. Set it to `undefined` to switch monitoring off |
-
-
-Changing `MuxDataSdk`, `beaconCollectionDomain`, `debug`, or `disableCookies` restarts monitoring, which ends the current view and starts a new one. The rest update the view in place.
+The MuxData reference lists every option: the metadata and software fields above, plus the beacon domain, cookie, debug, and SDK settings. Most options update the current view in place; changing `MuxDataSdk`, `beaconCollectionDomain`, `debug`, or `disableCookies` restarts monitoring, ending the current view and starting a new one.
## See also
+MuxData referenceMuxVideo element referenceMuxAudio element reference
-Google Cast — the other media component you compose onto a player
+Google Cast
diff --git a/site/src/content/docs/reference/google-cast.mdx b/site/src/content/docs/reference/google-cast.mdx
new file mode 100644
index 00000000..a67e4809
--- /dev/null
+++ b/site/src/content/docs/reference/google-cast.mdx
@@ -0,0 +1,62 @@
+---
+title: GoogleCast
+frameworkTitle:
+ html: google-cast
+description: Options for the Google Cast component that configures the receiver and load request
+---
+
+import FrameworkCase from '@/components/docs/FrameworkCase.astro';
+import DocsLink from '@/components/docs/DocsLink.astro';
+import DocsLinkCard from '@/components/docs/DocsLinkCard.astro';
+
+Adds Google Cast support to the player's media. It renders nothing — place it inside the player as a sibling of the media element, and pair it with a CastButton. See Google Cast for how casting works.
+
+## Anatomy
+
+
+```tsx
+import { GoogleCast } from '@videojs/react/media/google-cast';
+
+
+```
+
+
+
+```html
+
+```
+
+Register the element by importing `@videojs/html/media/google-cast`.
+
+
+## Options
+
+
+| Prop | Type | Description |
+|---|---|---|
+| `receiver` | `string` | Cast receiver application ID. Defaults to Google's Default Media Receiver (`CC1AD845`) |
+| `src` | `string` | Source URL loaded on the receiver. Defaults to the source the browser is playing |
+| `contentType` | `string` | MIME type of the Cast source. When unset, the receiver infers it from the URL |
+| `streamType` | `'on-demand' \| 'live'` | Stream type reported to the receiver. Falls back to the player's stream type |
+| `customData` | `object` | Custom data sent to the receiver with each load request |
+
+
+
+| Attribute | Property | Description |
+|---|---|---|
+| `receiver` | `receiver` | Cast receiver application ID. Defaults to Google's Default Media Receiver (`CC1AD845`) |
+| `src` | `src` | Source URL loaded on the receiver. Defaults to the source the browser is playing |
+| `content-type` | `contentType` | MIME type of the Cast source. When unset, the receiver infers it from the URL |
+| `stream-type` | `streamType` | Stream type reported to the receiver. Falls back to the player's stream type |
+| — | `customData` | Custom data sent to the receiver with each load request |
+
+`customData` takes an object, so it's a property only, with no matching attribute.
+
+
+When the Cast `src` is an HLS playlist, Video.js detects the segment format and sets the receiver's `hlsSegmentFormat` and `hlsVideoSegmentFormat` load-request fields. The Default Media Receiver plays HLS natively, so no extra receiver setup is needed.
+
+## See also
+
+Google Cast
+CastButton component reference
+Remote Playback feature reference
diff --git a/site/src/content/docs/reference/mux-data.mdx b/site/src/content/docs/reference/mux-data.mdx
new file mode 100644
index 00000000..df83a894
--- /dev/null
+++ b/site/src/content/docs/reference/mux-data.mdx
@@ -0,0 +1,70 @@
+---
+title: MuxData
+frameworkTitle:
+ html: mux-data
+description: Options for the Mux Data component that monitors playback quality
+---
+
+import FrameworkCase from '@/components/docs/FrameworkCase.astro';
+import DocsLink from '@/components/docs/DocsLink.astro';
+import DocsLinkCard from '@/components/docs/DocsLinkCard.astro';
+
+Adds [Mux Data](https://data.mux.com) monitoring to the player's media. It renders nothing — place it inside the player as a sibling of the media element. See Mux Data for how monitoring works.
+
+## Anatomy
+
+
+```tsx
+import { MuxData } from '@videojs/react/media/mux-data';
+
+
+```
+
+
+
+```html
+
+```
+
+Register the element by importing `@videojs/html/media/mux-data`.
+
+
+## Options
+
+
+| Prop | Type | Description |
+|---|---|---|
+| `envKey` | `string` | Mux Data environment key the beacons are sent to. Optional for Mux-hosted playback |
+| `metadata` | `object` | Mux Data metadata for the view |
+| `playerSoftwareName` | `string` | Player name reported to Mux Data |
+| `playerSoftwareVersion` | `string` | Player version reported to Mux Data. Defaults to the Video.js version |
+| `playerInitTime` | `number` | Epoch milliseconds the player was initialized. Defaults to when the component was created |
+| `beaconCollectionDomain` | `string` | Custom domain the beacons are sent to |
+| `disableCookies` | `boolean` | Stops the SDK from setting cookies |
+| `debug` | `boolean` | Turns on SDK debug logging |
+| `MuxDataSdk` | `object` | SDK used for monitoring. Set it to `undefined` to switch monitoring off |
+
+
+
+| Attribute | Property | Description |
+|---|---|---|
+| `env-key` | `envKey` | Mux Data environment key the beacons are sent to. Optional for Mux-hosted playback |
+| — | `metadata` | Mux Data metadata for the view |
+| `player-software-name` | `playerSoftwareName` | Player name reported to Mux Data |
+| `player-software-version` | `playerSoftwareVersion` | Player version reported to Mux Data. Defaults to the Video.js version |
+| `player-init-time` | `playerInitTime` | Epoch milliseconds the player was initialized. Defaults to when the element was created |
+| `beacon-collection-domain` | `beaconCollectionDomain` | Custom domain the beacons are sent to |
+| `disable-cookies` | `disableCookies` | Stops the SDK from setting cookies |
+| `debug` | `debug` | Turns on SDK debug logging |
+| — | `MuxDataSdk` | SDK used for monitoring. Set it to `undefined` to switch monitoring off |
+
+`metadata` and `MuxDataSdk` take objects, so they're properties only, with no matching attribute.
+
+
+Changing `MuxDataSdk`, `beaconCollectionDomain`, `debug`, or `disableCookies` restarts monitoring, which ends the current view and starts a new one. The rest update the view in place.
+
+## See also
+
+Mux Data
+MuxVideo element reference
+MuxAudio element reference
diff --git a/site/src/content/docs/reference/mux-video.mdx b/site/src/content/docs/reference/mux-video.mdx
index 18fc5705..d7cfc439 100644
--- a/site/src/content/docs/reference/mux-video.mdx
+++ b/site/src/content/docs/reference/mux-video.mdx
@@ -25,6 +25,89 @@ import basicUsageHtmlTs from "@/components/docs/demos/mux-video/html/css/BasicUs
Video element for playing Mux-hosted HLS streams. Built on hls.js with Mux-specific optimizations.
+## Load a source
+
+
+The `source` param builds the URL for you from a playback ID, an optional custom domain, and `playback` params. Playback params are just camelCased [Mux playback query params](https://www.mux.com/docs/api-reference/stream/streaming/get-hls-manifest); for example, `max_resolution` becomes `maxResolution`.
+
+```tsx
+
+```
+
+If for some reason you need a bit more control, you can use the `src` param with a plain 'ol URL, too:
+
+```tsx
+
+```
+
+MuxVideo fires a `sourcechange` event when the source actually changes. Setting the same values again, like a fresh object on a React re-render, doesn't fire it.
+
+
+
+
+MuxVideo takes Mux content two ways: a stream URL through `src`, or a structured `source` object.
+
+```html
+
+```
+
+The `source` object builds the URL for you from a playback ID, an optional custom domain, and `playback` params. Playback params are just camelCased [Mux playback query params](https://www.mux.com/docs/api-reference/stream/streaming/get-hls-manifest); for example, `max_resolution` becomes `maxResolution`.
+
+```ts
+const video = document.querySelector('mux-video');
+video.source = {
+ playbackId: 'BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM',
+ customDomain: 'media.example.com',
+ playback: { maxResolution: '1080p' },
+};
+```
+
+MuxVideo fires a `sourcechange` event when the source actually changes. Setting the same values again doesn't fire it.
+
+
+## Thumbnails and storyboards
+
+`thumbnail` and `storyboard` default to URLs derived from `source`: the poster image and the storyboard VTT that drives hover previews on the time slider. MuxVideo injects the storyboard `
-Mux Data — metadata, options, and configuration
-Google Cast — receivers, load requests, and session state
+Mux Data
+Google Cast
## Examples
diff --git a/site/src/docs.config.ts b/site/src/docs.config.ts
index 2a2afbfd..db8bc961 100644
--- a/site/src/docs.config.ts
+++ b/site/src/docs.config.ts
@@ -71,8 +71,10 @@ export const sidebar: Sidebar = [
{ slug: 'reference/cast-button' },
{ slug: 'reference/controls' },
{ slug: 'reference/fullscreen-button' },
+ { slug: 'reference/google-cast' },
{ slug: 'reference/menu' },
{ slug: 'reference/mute-button' },
+ { slug: 'reference/mux-data' },
{ slug: 'reference/pip-button' },
{ slug: 'reference/play-button' },
{ slug: 'reference/playback-rate-button' },