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.
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.
<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.
<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>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.
<!-- 720px max, centered -->
<div style="max-width:720px;margin:0 auto">
<div data-playflow-video="NiU95FjGxt"></div>
</div>| Attribute | Default | What it does |
|---|---|---|
data-playflow-video | required | The video code. |
data-aspect | from the video | Override the shape, e.g. 16/9. Rarely needed. |
data-autoplay | false | Start on load. Forces muted playback; see below. |
data-muted | false | Start silent, with the control available. |
data-loop | false | Restart on end. Best paired with autoplay and muted. |
data-controls | true | false hides the bar entirely. Only sensible for silent background video. |
data-start | 0 | Seconds 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.
Content Security Policy
If your site sends a CSP header, allow our origins:
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 see | Usually means |
|---|---|
| Nothing renders at all | The 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 sliver | An iframe with no aspect-ratio. |
| Plays on desktop, not on phones | Autoplay without muted. Add data-muted. |
Still stuck? Send us the page URL and we’ll look at it.