Embedding a video

Every video has a ten-character video code, like NiU95FjGxt in the examples below. You can find it under the title in the library, or on the video’s own page. That code is all an embed needs.

The video must be Public or Unlisted to play outside Playflow. A private video shows “This video is private” in the embed. See Visibility & sharing.

Script embed

The one we recommend. Drop the loader once per page, then a div wherever you want a video. It sizes itself, lazy-loads, and you can put as many on a page as you like.

HTML
<script src="https://getplayflow.co/embed.js" async></script>

<div data-playflow-video="NiU95FjGxt"></div>

The script scans for [data-playflow-video] on load and again whenever the DOM changes, so it works with React, Vue, HTMX and any site builder that injects markup after page load.

Iframe embed

Use this when you can’t add a script. Some CMS and email-adjacent tools only allow iframes.

HTML
<iframe
  src="https://getplayflow.co/e/NiU95FjGxt"
  style="aspect-ratio:16/9;width:100%;border:0"
  allow="autoplay; fullscreen; picture-in-picture"
  referrerpolicy="no-referrer"
  title="Onboarding tour"></iframe>
Set aspect-ratio yourself on an iframe. Unlike the script embed, an iframe can’t know the video’s shape before it loads, so without it you get a 150px-tall box.

Sizing and aspect ratio

The script embed reads the video’s real dimensions and applies the matching aspect-ratio, so a 9:16 phone video doesn’t get letterboxed into a widescreen frame. It fills the width of its container; to constrain it, constrain the parent.

HTML
<!-- 720px max, centered -->
<div style="max-width:720px;margin:0 auto">
  <div data-playflow-video="NiU95FjGxt"></div>
</div>
AttributeDefaultWhat it does
data-playflow-videorequiredThe video code.
data-aspectfrom the videoOverride the shape, e.g. 16/9. Rarely needed.
data-autoplayfalseStart on load. Forces muted playback; see below.
data-mutedfalseStart silent, with the control available.
data-loopfalseRestart on end. Best paired with autoplay and muted.
data-controlstruefalse hides the bar entirely. Only sensible for silent background video.
data-start0Seconds to begin at.

The full list, including the JavaScript API, is in embed.js options.

Autoplay and muting

Browsers block autoplay with sound. There is no way around it and no flag that changes it. If you set data-autoplay, we set muted too, because otherwise the browser would refuse to start and your visitor would see a still frame with no explanation.

If the video carries a voiceover, don’t autoplay it. A muted autoplay of a talking head reads as broken.

Content Security Policy

If your site sends a CSP header, allow our origins:

HTTP header
Content-Security-Policy:
  script-src 'self' https://getplayflow.co;
  frame-src https://getplayflow.co;
  media-src https://getplayflow.co https://*.getplayflow.co;
  img-src 'self' https://getplayflow.co data:;

If you serve the player from your own domain, swap getplayflow.co for it in frame-src and media-src. See Custom domains.

Troubleshooting

What you seeUsually means
Nothing renders at allThe loader didn’t run. Check the network tab for embed.js, and that the div isn’t inside a template that never mounted.
“This video is private”Visibility is Private. Switch it to Unlisted.
“Still processing”Encoding hasn’t finished. It clears itself; reload in a minute.
A 150px-tall sliverAn iframe with no aspect-ratio.
Plays on desktop, not on phonesAutoplay without muted. Add data-muted.

Still stuck? Send us the page URL and we’ll look at it.