> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # Custom head HTML migration guide This guide explains how to migrate custom `` markup from the legacy Bunny Stream player (Plyr-based) to the new Bunny Stream Player.\ It is based on typical customization patterns seen across customer integrations. ## **Introduction** The new Bunny Stream Player uses a modern Web Components architecture `media-chrome` + `bunny-*` instead of legacy Plyr internals. In practice, this means: * More explicit and readable player elements. * Easier CSS targeting through semantic element names and CSS variables. * Better long-term maintainability than deep framework-specific class selectors. Most migrations are straightforward: * Replace legacy `.plyr` and `[data-plyr="..."]` selectors. * Move styling to media-chrome and `bunny-*` element hooks. * Update any jQuery-dependent snippets to standard browser APIs. ## **Before you start** * Make sure your Video Library is using the new Bunny Stream Player in `Stream > Video Library > Player Settings`. * Keep a copy of your current custom snippet so you can test changes incrementally. * Validate migrated changes in your embedded iframe on desktop and mobile. ## **Who this is for** Customers who are using custom CSS and/or JavaScript in Bunny Stream `Player Settings` (custom head HTML/custom CSS snippet). ## **What changed** Legacy player: * Included Plyr, jQuery, and legacy player scripts in ``. * Exposed a Plyr-driven DOM `.plyr`, `.plyr__*`, `[data-plyr="..."]`. * Many snippets depended on those classes and globally available jQuery. New Bunny Stream Player: * Uses Web Components + media-chrome (`media-controller`, `media-*` controls, `bunny-*` components). * Does not render Plyr DOM/classes. * Does not bundle jQuery. * Still renders your custom head HTML (through the existing custom CSS field), but selectors and script hooks should be updated. ## **How to migrate custom markup** 1. Replace `.plyr` / `.plyr__*` selectors with media-chrome or `bunny-*` element selectors. 2. Replace `[data-plyr="..."]` control targeting with concrete elements like `media-pip-button`, `media-fullscreen-button`, etc. 3. Use CSS variables on `media-controller` and specific controls instead of deep, brittle selectors. 4. Replace jQuery-dependent scripts with vanilla JavaScript. ## **Legacy to new selector mapping** | Legacy selector | New selector | | :- | :- | | `.plyr` | `media-controller` | | `.plyr__controls` | `media-control-bar`, `bunny-media-control-bar` | | `.plyr__control` | `Specific elements` (`media-play-button`, `media-mute-button`, `etc`.) | | `.plyr__control--overlaid` | `media-play-button.large-play` | | `.plyr__poster` | `bunny-poster-image::part(img)`, `bunny-poster-video::part(video)` | | `.plyr__captions` | `bunny-captions-display` , `cue parts `(`[part='cue-display']`, `[part='cue']`) | | `.plyr__progress` | `bunny-media-time-range` | | `.plyr__volume` | `media-volume-range` | | `[data-plyr="play"]` | `media-play-button` | | `[data-plyr="mute"]` | `media-mute-button` | | `[data-plyr="captions"]` | `media-captions-button` | | `[data-plyr="pip"]` | `media-pip-button` | | `[data-plyr="fullscreen"]` | `media-fullscreen-button` | | `[data-plyr="airplay"]` | `media-airplay-button` | | `[data-plyr="settings"]` | `bunny-settings-menu-button` | | `[data-plyr="rewind"]` | `media-seek-backward-button` | | `[data-plyr="fast-forward"]` | `media-seek-forward-button` | ## **Migration examples** ### 1) Theme color and typography Legacy (Plyr): ```html theme={null} ``` New (Bunny Stream Player): ```html theme={null} ``` ### 2) Rounded player and poster styling Legacy (Plyr): ```html theme={null} ``` New (Bunny Stream Player): ```html theme={null} ``` ### 3) Hide specific controls (PiP and seek) Legacy (Plyr): ```html theme={null} ``` New (Bunny Stream Player): ```html theme={null} ``` ### 4) Captions styling Legacy (Plyr): ```html theme={null} ``` New (Bunny Stream Player): ```html theme={null} ``` ## **Migration checklist** 1. Search your custom snippet for `plyr`, `.plyr__`, and `data-plyr`. 2. Replace selectors using the mapping table. 3. Search for jQuery usage `($(, jQuery) `and rewrite to vanilla JavaScript. 4. Verify on desktop and mobile, especially controls and captions.   Migrating from Plyr-specific customizations to media-chrome element-based styling gives you a cleaner and more future-friendly setup. For the best results during migration: * Use your browser’s standard developer tools (Inspect Element, computed styles, and DOM viewer) to explore the current player structure. * Use stable element selectors and CSS variables over deep internal hooks. * Validate each customization incrementally so you can quickly isolate issues. This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.