Skip to content
FrameworkStyle

Go fullscreen and lock orientation

Present the player fullscreen with custom controls intact, and lock screen orientation on mobile.

Present the player fullscreen, with your custom controls intact, and optionally lock screen orientation while fullscreen on mobile.

Add a FullscreenButton inside the player container. It requests fullscreen on the container, so everything inside it — controls, captions, overlays — stays visible in the fullscreen presentation.

import { Container, createPlayer, FullscreenButton } 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 />
        <FullscreenButton
          className="media-fullscreen-button"
          render={(props, state) => <button {...props}>{state.fullscreen ? 'Exit Fullscreen' : 'Fullscreen'}</button>}
        />
      </Container>
    </Player>
  );
}

How it works

The fullscreen feature tracks fullscreen state and provides the actions:

  • fullscreen is true while the player is fullscreen, from any path — your button, native controls, or the platform presentation.
  • fullscreenAvailability is 'available', 'unavailable', or 'unsupported'. It starts as 'unavailable', then settles to 'available' or 'unsupported' when the feature attaches to a media element.
  • requestFullscreen(), exitFullscreen(), and toggleFullscreen() change the presentation. Requests target the player container when the Fullscreen API is available, falling back to the media element’s native presentation otherwise.

Fullscreen and picture-in-picture are exclusive: requesting fullscreen exits an active picture-in-picture presentation first.

Style fullscreen state through the container’s :fullscreen pseudo-class, or through the fullscreen state in components.

Availability and constraints

  • Fullscreen requests must come from a user gesture; browsers reject requests outside one.
  • iPhone Safari has no element Fullscreen API. The player falls back to the video’s native fullscreen presentation, which shows the system player UI instead of your custom controls. iPads support element fullscreen.
  • Orientation locking requires the Screen Orientation API with lock support — in practice, Android browsers in fullscreen. iOS doesn’t support programmatic orientation lock.
  • Inside iframes, fullscreen needs allow="fullscreen" on the embedding iframe.

Common variations

Lock orientation while fullscreen

Add orientationLockFeature to lock screen orientation while the player is fullscreen. It isn’t part of videoFeatures, so the preset VideoPlayer doesn’t include it. It locks to landscape by default and unlocks on exit.

Because the feature list changes, build the player yourself with createPlayer — the escape hatch for custom feature sets:

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

const { Player } = createPlayer({
  features: [...videoFeatures, orientationLockFeature],
});

export default function App() {
  return (
    <Player>
      <Container>
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" muted playsInline />
      </Container>
    </Player>
  );
}

To lock to something other than landscape, set orientationLockType on the player (the orientation-lock-type attribute in HTML). See the orientation lock feature reference for details.

Double-click to toggle

Use the Gesture component — the default skins ship this exact binding. Keep the button as the accessible path; gestures are a pointer-only shortcut.

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

<Gesture type="doubletap" action="toggleFullscreen" region="center" />

region="center" keeps the gesture off the left and right thirds, which the default skins reserve for double-tap seeking. See Add keyboard shortcuts and gestures for the full gesture surface.

Troubleshooting

The fullscreen request is rejected

The request didn’t come from a user gesture, fullscreen is unsupported, or an embedding iframe lacks allow="fullscreen".

Custom controls disappear in fullscreen on iPhone

Expected: iPhone Safari uses the native video presentation, which replaces custom UI with system controls. Design mobile controls assuming this fallback.

Orientation doesn’t lock

Orientation lock works in fullscreen on Android browsers; iOS doesn’t support it. Confirm orientationLockFeature is in your feature list.