Back

How to Embed Video in React

How to Embed Video in React

Embedding video in a React app sounds straightforward until you run into broken autoplay, a non-responsive iframe, or an <embed> tag that simply doesn’t work. This guide covers the two most practical approaches: the native HTML5 <video> element for self-hosted files, and <iframe> embeds for platforms like YouTube and Vimeo. Third-party libraries are mentioned where they genuinely add value, not as a default.

Key Takeaways

  • Use the native HTML5 <video> element for self-hosted files. No library required.
  • For YouTube embeds, a plain <iframe> pointing to youtube-nocookie.com is the standard, privacy-friendly approach.
  • Autoplay requires the muted attribute to work reliably across Chrome, Safari, and Firefox.
  • playsInline is essential on iOS to prevent forced fullscreen playback.
  • Reach for a library like ReactPlayer only when you need a unified API across multiple providers or advanced event callbacks.

Method 1: HTML5 Video in React for Self-Hosted Files

If you control the video file, the native <video> element is the right tool. No library needed.

import myVideo from './assets/demo.mp4';

export default function VideoPlayer() {
  return (
    <video
      width="100%"
      style={{ aspectRatio: '16/9' }}
      controls
      playsInline
      muted
    >
      <source src={myVideo} type="video/mp4" />
      <track
        kind="subtitles"
        src="/captions/demo.en.vtt"
        srcLang="en"
        label="English"
        default
      />
      Your browser does not support the video tag.
    </video>
  );
}

A few things worth noting:

  • autoPlay requires muted to work reliably across modern browsers. Chrome, Safari, and Firefox all block unmuted autoplay by default. Don’t assume it will work without muted. Note that in JSX the attribute is camelCased as autoPlay, not autoplay. Browser support and autoplay policies are documented on Can I Use.
  • playsInline is required on iOS to prevent the video from opening in fullscreen automatically.
  • <track> adds captions or subtitles. This is the right way to handle accessibility for video content, and it’s easy to overlook.
  • The fallback text inside <video> only appears in very old browsers that don’t recognize the element. It’s still worth including.

For adaptive streaming formats like HLS (.m3u8), native browser support varies. Safari handles HLS natively, but Chrome and Firefox require a library such as hls.js to parse and play the stream.

YouTube Embed in React: Using an iframe

For YouTube or Vimeo, an <iframe> is the standard approach. You don’t need a React-specific package for this.

export default function YouTubeEmbed({ videoId }) {
  return (
    <div style={{ aspectRatio: '16/9', width: '100%' }}>
      <iframe
        width="100%"
        height="100%"
        src={`https://www.youtube-nocookie.com/embed/${videoId}`}
        title="YouTube video player"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
        allowFullScreen
        style={{ border: 'none' }}
      />
    </div>
  );
}

Key details:

  • Use youtube-nocookie.com instead of youtube.com for the embed URL. This is YouTube’s privacy-enhanced mode, which reduces tracking cookies until the user interacts with the player.
  • title is required on iframes for screen readers. Without it, assistive technologies have no way to describe the embedded content.
  • aspectRatio: '16/9' on the wrapper with width: 100% and height: 100% on the iframe is the cleanest responsive approach using modern CSS. No padding hacks needed. Browser support for the CSS aspect-ratio property is available on Can I Use.
  • The embed URL format is https://www.youtube-nocookie.com/embed/{VIDEO_ID}. The video ID is the value of the v query parameter in a standard YouTube URL (for example, the part after ?v= in youtube.com/watch?v=VIDEO_ID).

You can pass additional parameters via the query string:

/embed/VIDEO_ID?controls=1&rel=0

When to Use a React Video Player Library

For most use cases, the native <video> element or a plain iframe is enough. Consider a library like ReactPlayer if you need to support multiple platforms (YouTube, Vimeo, Wistia, HLS, DASH) from a single component with a unified API, or if you need event callbacks like onReady, onProgress, or onEnded across different providers.

ReactPlayer adds meaningful bundle weight, so it’s worth evaluating whether you actually need that flexibility before adding it as a dependency.

Conclusion

Start with the simplest tool that works. For self-hosted video, use the HTML5 <video> element with controls, playsInline, and muted if autoplay is needed. For YouTube embeds in React, a plain <iframe> pointing to youtube-nocookie.com with a proper title attribute is all you need. Reach for a library only when the native approach genuinely falls short.

FAQs

Modern browsers block autoplay for videos with sound. To make autoplay work reliably in Chrome, Safari, and Firefox, your video element must include the muted attribute alongside autoPlay. On iOS, you also need playsInline, otherwise the video may refuse to play inline or open in fullscreen. Without these, autoplay will silently fail.

Use youtube-nocookie.com whenever possible. It is YouTube's privacy-enhanced embed mode, which avoids setting tracking cookies until the user actually interacts with the player. Core playback functionality is largely the same as standard embeds, but it is friendlier for privacy compliance and helps reduce third-party cookie warnings on your site.

Not for typical use cases. The native HTML5 video element handles self-hosted files, and a plain iframe handles YouTube or Vimeo. Reach for ReactPlayer only when you need a single unified API across multiple providers or consistent event callbacks like onProgress and onEnded. Otherwise, the bundle cost is rarely justified.

Wrap the video or iframe in a container styled with aspectRatio set to 16/9 and width 100%. Then set the inner element to width 100% and height 100%. This modern CSS approach replaces older padding-bottom hacks and keeps the video proportional across all screen sizes without manual calculations.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay