Quick Guide: Working with multiple embeds

The Aurora <wistia-player/> element does not utilize window._wq like our previous embed. For setting base configuration options, we recommend using our new window.wistiaOptions configuration object.

However, that configuration object does not give you a reference to each video element. So, what if you want to add event listeners or interact with the <wistia-player/>? You'll need to get it via Javascript. But, what if you don't know how many embeds are going to end up on the page, what their mediaId is going to be, or when they're going to be added to the page? And similarly, what if you need to do something when they are removed?

We can use native browser APIs and JavaScript to solve all these problems. The example code below uses the browser's MutationObserver API to watch the DOM for the addition and removal of elements. We check if those elements meet our criteria and then we act on them.

Example Code

Here we set up a new MutationObserver that checks to see if any newly added HTML elements are our <wistia-player/> element. If so, we log a message to the console and then also attach an event listener. Similarly, when a <wistia-player/> is removed from the DOM, we log another message and remove the event listener that we previously added.

<script src="https://fast.wistia.com/player.js" async></script>

<button id="btn-add">Add new Wistia Video!</button>
<button id="btn-remove">Remove Wistia Video</button>

<br />

<script>
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.type === 'childList') {
        const playEventCallback = (event) => {
          console.log(`Wistia player with media-id ${event.target.mediaId} started playing`);
        };
        mutation.addedNodes.forEach((node) => {
          if (node.nodeName === 'WISTIA-PLAYER') {
            node.addEventListener('play', playEventCallback);

            console.log('Wistia player added');
          }
        });

        mutation.removedNodes.forEach((node) => {
          if (node.nodeName === 'WISTIA-PLAYER') {
            node.removeEventListener('play', playEventCallback);

            console.log('Wistia player removed');
          }
        });
      }
    });
  });

  observer.observe(document.body, {
    childList: true,
    subtree: true,
  });
</script>

<script>
  const btnAdd = document.getElementById('btn-add');

  btnAdd.addEventListener('click', () => {
    const wistiaPlayer = document.createElement('wistia-player');
    wistiaPlayer.mediaId = 'rbsg3da4jd';

    document.body.appendChild(wistiaPlayer);
  });

  const btnRemove = document.getElementById('btn-remove');
  btnRemove.addEventListener('click', () => {
    const wistiaPlayer = document.querySelector('wistia-player[media-id="rbsg3da4jd"]');
    if (wistiaPlayer) {
      wistiaPlayer.remove();
    }
  });
</script>

Live Example


Performance on pages with many embeds

If you're building a gallery, a course catalog, or any page with a large number of videos, you might worry that mounting a Wistia player for every video will slow the page down. In practice, the Wistia player is built to stay lightweight until a viewer actually plays a video — so a page with many embeds is usually fine, as long as you understand what loads when.

The script loads once

You only need the player.js script tag once on the page, no matter how many videos you embed. Each additional <wistia-player/> reuses that already-loaded script — adding more players does not re-download it.

<!-- One script tag, anywhere on the page -->
<script src="https://fast.wistia.com/player.js" async></script>

<wistia-player media-id="abc123abc1"></wistia-player>
<wistia-player media-id="def456def4"></wistia-player>
<wistia-player media-id="ghi789ghi7"></wistia-player>

Players are lazy by default

A <wistia-player/> does not download the full video on page load. By default it renders a thumbnail and only loads enough of the video to make playback feel snappy — then loads the rest once the viewer clicks play. You control how much it preloads with the preload attribute:

preload valueBehavior
metadata (default)Loads the thumbnail and just enough video data to start quickly when clicked.
noneLoads only the thumbnail — no video data until the viewer plays. Lightest option for pages with many embeds.
autoPreloads more of the video up front so playback is immediate. Heaviest.

For a page with many videos, set preload="none" on the players below the fold so the page only does the minimal work to render each thumbnail:

<wistia-player media-id="abc123abc1" preload="none"></wistia-player>

See the preload embed option for full details.

For galleries, use a popover (click-to-play) embed

If your page is a grid or list where viewers pick one video to watch, a popover embed is the cleanest fit. It renders as a lightweight thumbnail or your own trigger element, and only opens the full player in a lightbox when clicked — so the page stays light and one video plays at a time.

<script src="https://fast.wistia.com/player.js" async></script>

<!-- Thumbnail trigger -->
<wistia-player media-id="abc123abc1" wistia-popover></wistia-player>

<!-- Or trigger from your own HTML (a link, button, image, etc.) -->
<wistia-player media-id="abc123abc1" wistia-popover popover-content="html">
  <a href="#">Watch the demo</a>
</wistia-player>

See the Aurora Popover Player API for the full set of popover attributes and behavior.

📘

Before you build a custom lazyloader

A common instinct is to wrap embeds in a homegrown script that swaps players in as the user scrolls. Because the player is already lazy by default — and preload="none" plus popovers cover the heavy cases — you usually don't need one. If you have a page where the supported options above still aren't enough, reach out to Wistia support before rolling your own; a custom loader is easy to get subtly wrong and can break accessibility and deep-linking.