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.
Recommended approach
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>
);
}
.media-container {
position: relative;
}
.media-container video {
width: 100%;
}
.media-fullscreen-button {
position: absolute;
right: 10px;
bottom: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
<video-player class="video-player">
<media-container>
<video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoplay muted playsinline loop></video>
<media-fullscreen-button class="media-fullscreen-button">
<span class="fullscreen">Exit Fullscreen</span>
<span class="not-fullscreen">Fullscreen</span>
</media-fullscreen-button>
</media-container>
</video-player>
.video-player media-container {
position: relative;
display: block;
}
.video-player media-container video {
width: 100%;
}
.media-fullscreen-button {
position: absolute;
right: 10px;
bottom: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
.media-fullscreen-button .fullscreen {
display: none;
}
.media-fullscreen-button .not-fullscreen {
display: none;
}
.media-fullscreen-button[data-fullscreen] .fullscreen {
display: inline;
}
.media-fullscreen-button:not([data-fullscreen]) .not-fullscreen {
display: inline;
}
import '@videojs/html/video/player';
import '@videojs/html/ui/container';
import '@videojs/html/ui/fullscreen-button';
How it works
The fullscreen feature tracks fullscreen state and provides the actions:
fullscreenistruewhile the player is fullscreen, from any path — your button, native controls, or the platform presentation.fullscreenAvailabilityis'available','unavailable', or'unsupported'. It starts as'unavailable', then settles to'available'or'unsupported'when the feature attaches to a media element.requestFullscreen(),exitFullscreen(), andtoggleFullscreen()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>
);
}Compose a player with orientationLockFeature in its feature list through createPlayer; the prebuilt <video-player> element doesn’t include it.
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" /><media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
<script type="module">
import '@videojs/html/ui/gesture';
</script>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.