Dynamically load Twitch Embed JavaScript

I’m trying to embed a Twitch stream in a dynamic based web app, think React. The Twitch Embed Everything doc give the example of adding the following to your <body>

 <!-- Load the Twitch embed JavaScript file -->
<script src="https://embed.twitch.tv/embed/v1.js"></script>

And this works fine at the top of my app. However, I don’t want to load the Twitch JS library for every client if they don’t need it.

So I’m trying to dynamically load the above script by triggering a flag that then loads. The problem is all the dynamic methods of loading successfully load the script and I can see it in my Developer Tools → Sources tab in Chrome, but window.Twitch never gets set and is undefined.

I’ve tried loading it with a jquery ajax call:

$.getCachedScript("https://embed.twitch.tv/embed/v1.js")
    .done(function() {
      // window.Twitch returns undefined even after waiting
    )}

I’ve tried loading it by building a <script> element and adding it to the <body> or <head> elements:

let script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://embed.twitch.tv/embed/v1.js";
$("head").append(script); 

I’ve even added a listener for the load event on the script object and the script successfully loads. I just cannot access window.Twitch anywhere.

Why does the script only work if it’s hard-coded into the <body> or <head>?

After spending two days, I figured this out no later than 20 minutes after posting this. :confused: Maybe this will help someone else with this problem.

The issue is the Twitch code has this line at the top that tries to detect its environment and how it will make Twitch (which is t()) available:

"object" == typeof exports && "object" == typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define([], t) : "object" == typeof exports ? exports.Twitch = t() : e.Twitch = t()

Upon using a little Github Copilot to break that down, the script detects exports and module in my Meteor application and then sets module.exports = t() which sets Twitch as an export of this module. It never makes it to last else of the inline if which is e.Twitch = t() which would set Twitch into the global window object. So that’s why window.Twitch is never set.

After figuring this out, it was a matter if finding where the script’s exports are at. Logging modules after the $.getScript(...) success showed that Twitch was inside of modules.parent.parent.exports which ended up being the client entry point JS file of my Meteor app.

So in the .done callback of $.getScript(...) I needed to do:

//  Access the set export from the Twitch Embed script
const { Twitch } = require("/client/main.js");

//  Set the Twitch object to the window for the rest of the app to use as normal
window.Twitch = Twitch;

Dynamically loading the Twitch Embed JS library with no source modifications.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.