Skip to content
FrameworkStyle

MuteButton

Accessible mute/unmute button with keyboard support and volume state reflection

Import

import { MuteButton } from '@videojs/react';

Anatomy

<MuteButton />

Behavior

Toggles mute on and off, and exposes a derived volumeLevel based on the current volume and mute state.

Mute availability is separate from volume-level availability because some media can accept a mute command without supporting volume changes. When mute is unavailable or unsupported, the HTML custom element receives the native hidden attribute and the React component returns null. Toggling is also ignored while mute is unavailable.

Styling

Attribute Values Description
data-muted Present / absent Present when the media is muted
data-volume-level "off" | "low" | "medium" | "high" Current volume level
data-availability "available" | "unavailable" | "unsupported" Whether the media can be muted
data-hidden Present / absent Present on the HTML element while mute is unavailable or unsupported

Style the button based on muted state:

React renders a <button> element. Add a className to style it:

.mute-button[data-muted] .icon-muted { display: inline; }
.mute-button:not([data-muted]) .icon-unmuted { display: inline; }

Use data-volume-level for multi-level icon switching:

.mute-button[data-volume-level="off"] .icon-off { display: inline; }
.mute-button[data-volume-level="low"] .icon-low { display: inline; }
.mute-button[data-volume-level="medium"] .icon-medium { display: inline; }
.mute-button[data-volume-level="high"] .icon-high { display: inline; }

Unavailable and unsupported buttons are hidden automatically. No availability selector or extra hiding CSS is required.

Accessibility

Renders a <button> with an automatic aria-label: “Unmute” when muted, “Mute” when unmuted. Override with the label prop. Keyboard activation: Enter / Space.

Examples

Basic Usage

import { Container, createPlayer, MuteButton } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';

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

export default function BasicUsage() {
  return (
    <Player>
      <Container className="media-container">
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoPlay muted playsInline loop />
        <MuteButton
          className="media-mute-button"
          render={(props, state) => <button {...props}>{state.muted ? 'Unmute' : 'Mute'}</button>}
        />
      </Container>
    </Player>
  );
}

Volume Levels

import { Container, createPlayer, MuteButton } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';

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

export default function VolumeLevels() {
  return (
    <Player>
      <Container className="media-container">
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoPlay muted playsInline loop />
        <MuteButton
          className="media-mute-button"
          render={(props, state) => (
            <button {...props}>
              {state.volumeLevel === 'off'
                ? 'Off'
                : state.volumeLevel === 'low'
                  ? 'Low'
                  : state.volumeLevel === 'medium'
                    ? 'Medium'
                    : 'High'}
            </button>
          )}
        />
      </Container>
    </Player>
  );
}

API Reference

Props

PropTypeDefaultDetails
disabledbooleanfalse
labelobject''

State

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

PropertyTypeDetails
mutedboolean
label{ key: string; text: string } | string
volumeLevel'off' | 'low' | 'medium' | 'high'
availabilityMediaFeatureAvailability
hiddenboolean

Data attributes

AttributeTypeDetails
data-muted
data-volume-level'off' | 'low' | 'medium' | 'high'
data-availabilityMediaFeatureAvailability
data-hidden