DEV Community

Kanak Waradkar
Kanak Waradkar

Posted on

How I Hijacked YouTube Music's DOM to Build a Custom Mini-Player 🎵

The Challenge: Dealing with Aggressive UI "Pruning"

YouTube Music is built with a highly responsive engine. When you narrow the window to a "mini" size—essential for a browser extension mini-player—YTM starts aggressively pruning the interface. One of the first things to go are the Like and Dislike buttons. They aren't just hidden; they are often completely stripped from the active layout to save space.

Previous interface of the YouTube Music Player

For a multitasking user, having to expand the player just to "Like" a song is a major friction point.

The Strategy: Native Reparenting (DOM Hijacking)

Initially, I tried simulating keyboard shortcuts (Shift + =), but found it unreliable when the window lost focus. I also tried creating custom buttons, but syncing their state (Blue for liked, Red for disliked) with YTM's internal player was complex and prone to breaking.

The solution? Native Reparenting. Instead of building new buttons, I "stole" the official ones and moved them into my own persistent UI.

Step 1: Locating the Native Renderer

Even when hidden, the native ytmusic-like-button-renderer component often persists in the DOM (hidden in the background player page). We simply need to find it.

const nativeRenderer = document.querySelector('ytmusic-like-button-renderer');
Enter fullscreen mode Exit fullscreen mode

Step 2: Creating a Custom Pill Container

To give the buttons a modern, floating feel, I created a custom "Pill Bar" with glassmorphism effects.

const container = document.createElement('div');
container.id = 'ytm-pill-container';
document.body.appendChild(container);
Enter fullscreen mode Exit fullscreen mode

Step 3: The "Hijack"

This is the magic line. By appending the native renderer to our new container, we move the actual functional component—including its click handlers and state management—out of its original location and into our floating UI.

if (nativeRenderer && nativeRenderer.parentElement !== container) {
    // Clear any existing content to prevent duplicates
    container.innerHTML = ''; 
    container.appendChild(nativeRenderer);
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Overriding the Style Engine

Because YTM's CSS still thinks these buttons should be hidden in narrow windows, we have to use high-priority !important rules to force them back into visibility.

#ytm-pill-container ytmusic-like-button-renderer {
    display: flex !important;
    visibility: visible !important;
}
Enter fullscreen mode Exit fullscreen mode

The Result: A Robust, Draggable UI

By using the native components, we get 100% reliable Like/Dislike functionality. We even added draggability so users can move the pill bar anywhere in the window.

New movable floating pill


🚀 Links

Happy coding!

Top comments (0)