Plugin overview
Every Playerstack feature beyond “play a video” is a plugin. The standalone bundle pre-registers 16 of them; sellf-adapter is opt-in.
Marketing
| Plugin | What it does |
|---|---|
| intro-card | Pre-roll splash with title, subtitle, badge, CTA, big play button |
| branded-thumb | Custom poster + click-to-load (LCP + GDPR) |
| cta-end | Overlay HTML at end of video, button with UTM, replay |
| action-bar | Mid-video dismissible banner with CTA |
| email-gate | Lead capture: pause and require email to keep watching |
| yt-subscribe | Subscribe-on-YouTube bar below the player |
| autopreview | Muted autoplay when in viewport |
E-Learning
| Plugin | What it does |
|---|---|
| chapters | Clickable chapter list, syncs with playback |
| saved-position | Resume watching where the visitor left off |
| focus-mode | Auto-pause when the tab loses focus |
Performance & UX
| Plugin | What it does |
|---|---|
| sources | Auto-detects YT/Vimeo/MP4/HLS/WebM/DASH from one URL |
| controls-policy | Theme color, show/hide controls |
| sticky | Pin to viewport corner when scrolled past |
Branding
| Plugin | What it does |
|---|---|
| watermark | Corner-pinned logo or text overlay, optional click-through |
| custom-css | Inject arbitrary scoped CSS — escape hatch for anything controls-policy lacks |
Analytics & Integrations
| Plugin | What it does |
|---|---|
| analytics | Forward events to a beacon endpoint or gtag |
| sellf-adapter | Load config from a Sellf product endpoint (opt-in) |
Plugin lifecycle
Each plugin is an object with name, init(ctx), and an optional destroy(ctx).
When <player-stack> connects to the DOM:
- The current
ConfigProviderloads config from the element (default: inline attributes +data-config) <media-player>is mounted with the configinit(ctx)runs on each registered plugin in registration orderinitis awaited — async plugins block later plugins (rare, but supported)
When the element disconnects:
destroy(ctx)runs on each plugin in reverse order- Errors in destroy are caught and logged so all plugins get cleaned up
See Core API for the full interface.
Multi-instance safety
Every first-party plugin uses a WeakMap<PlayerstackContext, ...> for per-element state. You can put dozens of <player-stack> elements on one page with different configs — they don’t collide.
When you write your own plugin (see Recipes), use the same pattern.