NEWMeet the new Video Gallery — YouTube, TikTok, Instagram Reels, Vimeo and Twitch in one widget.

Find a widget for you

You can use our widgets to accomplish practically any task on your website — increase users' confidence, grow conversion, engage your visitors, provide support, etc.

See All Widgets
GuideVideo Gallery

YouTube IFrame API: A Practical Guide

Updated September 2026 · 19 min read

Short answer

The YouTube IFrame Player API lets JavaScript control an embedded player: load videos, play, pause, seek and listen for events. Load the API script, create a YT.Player and use its methods.

Key takeaways

  • Load https://www.youtube.com/iframe_api once and create players in onYouTubeIframeAPIReady.
  • Control playback with playVideo, pauseVideo, seekTo, mute and loadVideoById.
  • React to onStateChange and onError to track plays and skip broken videos.
  • The IFrame API needs no key; listing channel or playlist videos needs the YouTube Data API with a key and quotas.

Load the API and create a player

<div id="player"></div>
<script src="https://www.youtube.com/iframe_api"></script>
<script>
  let player;
  function onYouTubeIframeAPIReady() {
    player = new YT.Player("player", {
      videoId: "VIDEO_ID",
      playerVars: { playsinline: 1, rel: 0 },
      events: { onReady: e => e.target.mute().playVideo() }
    });
  }
</script>

Common methods

MethodDoes
playVideo() / pauseVideo()Play and pause
seekTo(seconds)Jump to a time
mute() / unMute()Sound control
loadVideoById(id)Switch videos
getCurrentTime()Current position

Events

onReady, onStateChange (playing, paused, ended), onError. Use them to track views or start the next video.

When you don’t need the API

For a gallery, playlist or channel feed on marketing pages, the API is a lot of code to maintain.

The no-code way

Show YouTube videos in a player with playlist — no API code.

Try Elfsight Video Gallery →

How the API loads

The IFrame API is a single script. When it finishes loading, it calls a global function named onYouTubeIframeAPIReady — create your players there. Load the script once per page, even if you have several players, and create each player on its own element.

const players = {};
function onYouTubeIframeAPIReady() {
  document.querySelectorAll("[data-yt]").forEach((el) => {
    players[el.id] = new YT.Player(el.id, {
      videoId: el.dataset.yt,
      playerVars: { rel: 0, playsinline: 1 }
    });
  });
}

Player states

ValueConstantMeaning
-1—Unstarted
0YT.PlayerState.ENDEDEnded
1YT.PlayerState.PLAYINGPlaying
2YT.PlayerState.PAUSEDPaused
3YT.PlayerState.BUFFERINGBuffering
5YT.PlayerState.CUEDVideo cued

Listen to onStateChange and compare event.data with these constants.

Build a custom play button

<div id="player"></div>
<button id="play">Play</button>
<script>
  let player;
  function onYouTubeIframeAPIReady() {
    player = new YT.Player("player", { videoId: "VIDEO_ID", playerVars: { controls: 0 } });
  }
  document.getElementById("play").onclick = () => {
    const s = player.getPlayerState();
    s === YT.PlayerState.PLAYING ? player.pauseVideo() : player.playVideo();
  };
</script>

Hiding YouTube’s controls means you take responsibility for accessible controls — keyboard support and labels.

Track plays and completions

events: {
  onStateChange: (e) => {
    const title = e.target.getVideoData().title;
    if (e.data === YT.PlayerState.PLAYING) gtag("event", "video_start", { video_title: title });
    if (e.data === YT.PlayerState.ENDED)   gtag("event", "video_complete", { video_title: title });
  }
}

Handle errors

CodeMeaningWhat to do
2Invalid parameter (often a wrong video ID)Check the ID
5HTML5 player errorRetry or show a fallback
100Video not found or privateRemove it from the list
101 / 150Owner doesn’t allow embeddingLink to YouTube instead

Listen to onError and skip to the next video in your list when an error occurs.

IFrame API vs. YouTube Data API

The IFrame API controls playback of videos you already know. To list a channel’s uploads or a playlist’s videos, you need the separate YouTube Data API — with an API key, daily quota limits and caching on your side. That’s the part most custom galleries underestimate.

The no-code way

Show a channel or playlist as a gallery without the Data API, keys or quotas.

Try Elfsight Video Gallery →

A complete example: a playlist of product videos

A common use case: one player, a list of your product videos next to it, and analytics for each play. Create the player once, render your list as buttons with data-id attributes, and call loadVideoById on click. On ENDED, load the next ID in your list so the playlist continues. Send video_start and video_complete events to analytics with the video title. Everything else — thumbnails, titles, the order of videos — comes from your own data, which is exactly the part the Data API or a gallery widget provides.

Frequently asked questions

What is the YouTube IFrame API?

A JavaScript API that controls embedded YouTube players.

Do I need an API key?

No, the IFrame Player API doesn’t need a key. The YouTube Data API (for listing channel videos) does.

Can I use the IFrame API with several players?

Yes — load the script once and create one YT.Player per element.

Why doesn’t playVideo() start with sound on mobile?

Browsers block unmuted playback without a user gesture; call it from a click, or mute first.

Can I autoplay with the IFrame API?

Yes, if the player is muted (playerVars mute: 1 or player.mute()) — the same browser rules apply as for iframes.

How do I get the current time of the video?

Call player.getCurrentTime() — for example on an interval while the state is PLAYING.

How do I switch videos without reloading the player?

Use player.loadVideoById(id) to load and play, or cueVideoById(id) to load without playing.

Does the API work with Shorts?

Yes — Shorts have regular video IDs; use a 9:16 container.

Official documentation

Related

Put your videos on your website

Create a free video gallery in minutes.

Create Widget for Free