# YouTubeVideo

Video component that plays YouTube videos and playlists through the YouTube IFrame player

The [YouTube IFrame player](https://developers.google.com/youtube/iframe_api_reference) keeps its own chrome hidden by default, so it drops into a [player skin](https://videojs.org/docs/framework/react/guides/skins) like any other media component; set `controls` to use YouTube’s UI instead.

## Import

```bash
pnpm add @videojs/youtube-video
```

```tsx
import { YouTubeVideo } from '@videojs/react/media/youtube-video';
```

## Load a source

`src` takes a YouTube URL or a raw 11-character video id. Watch, share (`youtu.be`), embed, Shorts, live, and privacy-enhanced (`youtube-nocookie.com`) URLs all work. Playlist URLs load through their `list` parameter, and a `t` parameter sets the start position.

```tsx
<YouTubeVideo src="https://www.youtube.com/watch?v=aqz-KE-bpKQ" />
```

## Behavior

A few things work differently from a native `<video>` element, because the IFrame API doesn’t expose them:

- `loop` restarts playback when the video ends; the IFrame API has no single-video loop.
- Fullscreen targets the iframe, so YouTube’s own chrome shows in fullscreen.
- Picture-in-picture is unavailable, and the player reports it as unsupported.
- Caption tracks appear in `textTracks` once playback starts; YouTube reports no caption metadata before then.

## Examples

### Basic Usage

**App.tsx**

```tsx
import { YouTubeVideo } from '@videojs/react/media/youtube-video';

export default function BasicUsage() {
  return (
    <div className="youtube-video">
      <YouTubeVideo src="https://www.youtube.com/watch?v=aqz-KE-bpKQ" controls />
    </div>
  );
}
```

**App.css**

```css
.youtube-video {
  width: 100%;
  aspect-ratio: 16 / 9;
}
```

## API Reference

### Props

Accepts these Video.js-specific props:

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `autoplay` | `boolean` | `false` | |
| `controls` | `boolean` | `false` | |
| `defaultMuted` | `boolean` | `false` | |
| `loop` | `boolean` | `false` | |
| `muted` | `boolean` | `false` | |
| `playsInline` | `boolean` | `true` | |
| `poster` | `string` | `''` | |
| `preload` | `MediaPreloadType` | `'metadata'` | |
| `source` | `{ src?: string; engine?: YouTubeSourceEngineConfig } \| null` | `null` | YouTube URL or id in `src`, plus player parameters under `engine.youtube`. Replacing it re-derives `src`. |
| `src` | `string` | `''` | |

### Engine options

#### `source.engine.youtube`

Pass [YouTube player parameters](https://developers.google.com/youtube/player_parameters) under `source.engine.youtube`, spelled exactly as YouTube spells them. They’re serialized onto the embed URL untouched, and the embed reads them once, when its URL is built. [Media Sources](https://videojs.org/docs/framework/react/guides/media-sources) covers how engine options fit into a structured source.

`autoplay`, `controls`, and `playsinline` come from the props of the same name, so they have no `engine.youtube` spelling. Parameters YouTube has deprecated are absent as well: `modestbranding`, `showinfo`, `autohide`, `theme`, and `listType: 'search'`. Anything YouTube adds next passes through the same way.

```tsx
<YouTubeVideo
  source={{
    src: 'https://www.youtube.com/watch?v=aqz-KE-bpKQ',
    engine: { youtube: { hl: 'de', cc_load_policy: 1 } },
  }}
/>
```

| Option | Type | Description |
| --- | --- | --- |
| `cc_lang_pref` | `string \| undefined` | ISO 639-1 language to display captions in. Pair with `cc_load_policy`. |
| `cc_load_policy` | `1 \| undefined` | Show closed captions by default, even if the viewer has turned them off. |
| `color` | `'red' \| 'white' \| undefined` | Progress-bar highlight color. Defaults to `'red'`. |
| `disablekb` | `0 \| 1 \| undefined` | Stop responding to keyboard controls. Defaults to `0`. |
| `enablejsapi` | `0 \| 1 \| undefined` | Allow the player to be driven through the IFrame Player API. Defaults to `0`. |
| `end` | `number \| undefined` | Stop playback this many seconds from the start of the video. |
| `fs` | `0 \| 1 \| undefined` | Display the fullscreen button. Defaults to `1`. |
| `hl` | `string \| undefined` | Player interface language: an ISO 639-1 code or full locale (`fr`, `fr-ca`). |
| `iv_load_policy` | `1 \| 3 \| undefined` | Show video annotations (`1`) or hide them (`3`). Defaults to `1`. |
| `list` | `string \| undefined` | Playlist id (prefixed with `PL`) or channel name, depending on `listType`. |
| `listType` | `'playlist' \| 'user_uploads' \| undefined` | What `list` refers to. |
| `loop` | `0 \| 1 \| undefined` | Repeat playback. Looping a single video also needs `playlist` set to the same id. |
| `origin` | `string \| undefined` | Embedding domain. Set it whenever `enablejsapi` is `1`. |
| `playlist` | `string \| undefined` | Comma-separated video ids to play after the one named by the URL path. |
| `referrerPolicy` | `ReferrerPolicy \| undefined` | `referrerpolicy` for the embed iframe. Not a YouTube player parameter. |
| `rel` | `0 \| 1 \| undefined` | Draw related videos from the same channel (`0`) or anywhere (`1`). Defaults to `1`. |
| `start` | `number \| undefined` | Begin playback this many seconds from the start of the video. |
| `widget_referrer` | `string \| undefined` | Embedding URL reported to YouTube Analytics for widget-hosted players. |

### Ref

Forwards its ref to the rendered `<iframe>`. The ref is an [HTMLIFrameElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement). Control playback with the component props and player APIs rather than the iframe ref.

### Events

Handle standard media events with React event props such as `onPlay` and `onTimeUpdate`. For native events without a React prop, attach a listener through the ref with `addEventListener`.

---

React documentation: https://videojs.org/docs/framework/react/llms.txt
All documentation: https://videojs.org/llms.txt
