I’m trying to integrate a Twitch player embed into my Vue.js app but running into issues with event handling. The player renders correctly and streams work fine, but none of the event listeners seem to trigger when the player container is inside my Vue instance.
const streamConfig = {
width: 500,
height: 350,
channel: "gaming"
};
const twitchPlayer = new Twitch.Player("player-container", streamConfig);
const app = new Vue({
el: "#main-app",
methods: {
setupPlayer: function() {
twitchPlayer.addEventListener(Twitch.Player.READY, () => {
console.log("Stream player loaded successfully!");
});
}
},
mounted: function() {
this.setupPlayer();
}
});
<div id="main-app">
<div id="player-container"></div>
</div>
The weird thing is that when I move the player div outside of the Vue app container, everything works perfectly. Event listeners fire as expected and I can call player methods like getChannel() without problems. But inside the Vue instance, it’s like the events are being blocked somehow.
I even tried using v-pre directive on the player container hoping Vue would ignore it completely, but that didn’t help either. Has anyone encountered this before? Is there a way to make Twitch player events work properly while keeping the player inside my Vue app?
Vue’s probably messing with event bubbling. Add your event listeners with vanilla JS after the player container mounts instead of using Vue’s methods. Also check if you’re calling stopPropagation() anywhere in your components - that’ll break Twitch events instantly.
I’ve hit this exact issue before. You’re probably initializing the Twitch player before the DOM element is ready, even in mounted(). Vue might still be processing when the player tries to attach.
Wrap your player setup in this.$nextTick(() => { /* your player code */ }) so Vue finishes rendering first. Also check you’re not accidentally reinitializing the player elsewhere in your component lifecycle.
One more thing - any CSS transitions or animations on the parent container? I had a case where a CSS transform broke the player’s event listeners completely.
I’ve hit this with other third-party embeds in Vue. Usually happens because Vue’s reactive system messes with external libraries that need static DOM elements. Try using a ref for the player instance instead of targeting by ID, and destroy it properly in beforeDestroy() to avoid memory leaks. What worked for me was moving the Twitch player setup completely outside Vue’s lifecycle - initialize it in a separate function after Vue mounts, then expose just the methods you need through Vue’s data. The player runs independently from Vue’s reactivity but you can still control it from your components.
Had the same issue with Twitch embedded players in Vue. Vue’s probably messing with the iframe communication that Twitch needs for events. Try making the player instance a global variable outside your Vue component completely - just reference it from inside Vue when you need it. What worked for me was using a mutation observer to watch for when the Twitch iframe actually loads, then attach listeners after that instead of relying on Vue’s lifecycle hooks. The timing between Vue’s DOM updates and Twitch’s iframe setup gets weird. Also check if any Vue plugins or mixins are grabbing events globally in your app.