Skip to content
FrameworkStyle

CaptionsRadioGroup

A menu radio group for selecting caption and subtitle tracks

Creates radio items from the player text track state and selects the showing caption or subtitle track.

Anatomy

<CaptionsRadioGroup
  renderItem={(props, item) => (
    <Menu.RadioItem {...props}>
      {item.label}
      <Menu.ItemIndicator checked={item.checked} />
    </Menu.RadioItem>
  )}
/>

Behavior

The group is available when the configured media exposes at least one caption or subtitle track. The first generated option is Off; selecting it hides captions. Track labels use the track label, then language, then kind. Pass formatTrack to customize the visible labels.

CaptionsRadioGroup uses useCaptionsOptions to own selection and generate each item, including Off. Its required renderItem callback renders the Menu.RadioItem root and receives item state containing the translated label and current checked value. It returns null when the text tracks feature is not configured.

Styling

Attribute Values Description
data-active Present / absent Present when captions are enabled.
data-disabled Present / absent Present when track selection is disabled.
data-hidden Present / absent Present when caption or subtitle tracks are unavailable.
data-availability "available" / "unavailable" Whether caption or subtitle tracks are available.

Unavailable groups receive the native hidden attribute.

Accessibility

The group uses the menu radio group pattern.

The component receives an accessible label from the label prop or defaults to Captions. Override it with aria-label or aria-labelledby.

Examples

Basic usage

import { CaptionsRadioGroup, Container, createPlayer, Menu } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
import type { ReactNode } from 'react';

const { Player } = createPlayer({ features: videoFeatures });

function CaptionsMenu(): ReactNode {
  return (
    <Menu.Root side="top" align="end">
      <Menu.Trigger className="settings-trigger" render={<button type="button" />}>
        Captions
      </Menu.Trigger>
      <Menu.Content className="menu">
        <CaptionsRadioGroup
          className="menu-group"
          renderItem={(props, item) => (
            <Menu.RadioItem {...props} className="menu-item">
              {item.label}
              <Menu.ItemIndicator checked={item.checked} forceMount className="menu-indicator">

              </Menu.ItemIndicator>
            </Menu.RadioItem>
          )}
        />
      </Menu.Content>
    </Menu.Root>
  );
}

export default function BasicUsage() {
  return (
    <Player>
      <Container className="media-container">
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoPlay muted playsInline loop>
          <track kind="captions" src="/docs/demos/captions-button/captions.vtt" srcLang="en" label="English" />
          <track kind="subtitles" src="/docs/demos/captions-button/captions.vtt" srcLang="es" label="Spanish" />
        </Video>
        <div className="menu-bar">
          <CaptionsMenu />
        </div>
      </Container>
    </Player>
  );
}

API Reference

Props

PropTypeDefaultDetails
disabledbooleanfalse
formatTrackText) | functionformatTrackLabel
labelText | string | Text) | function''

State

State is accessible via the render, className, and style props.

PropertyTypeDetails
subtitlesShowingboolean
valuestring
optionsCaptionsRadioGroupOption[]
disabledboolean
hiddenboolean
availability'available' | 'unavailable'
labelText | string

Data attributes

AttributeTypeDetails
data-active
data-disabled
data-hidden
data-availability'available' | 'unavailable'