Question before I go down this Troubleshooting rabbit hole

So I have figured out that even if its a local webpage iframes and embeds do not work. Would an object?

To explain what I am trying to do

Main menu ->programically creates buttons based on the json data
main menu → programically adds the local webpage with a post argument (example ?p=player1)

main menu pulls data, verifies that it changed (else do nothing) breaks out the JSON into its individual records for the characters and feeds those to the individual charactersheet pages that then put the data in the correct locations for each instance of that page.

Its starting to dawn on me that I may need to make the menu write the entire webpage for each instance of characters in the json. I’d like to avoid doing this.

So the question is, would Objects work, or do I need to add * to the correct allow lists for the iframe/embeds to work? Like I said, these are pointing to an html page within the extension file system.

If neither, then the only other option I can think of is having the main menu write the full page manually and change how I feed them the data from the json.

I run a number of extensions that fetch a JSON Blob from my server and parse it to a JavaScript object, and then my javascript builds a page from that blob.

Usually populating a predefined HTML template with the data. (A DnD character sheet for example)

I understand what you are saying, but just to make sure I’m clear.

Iframes, Objects, and embeds cannot be used. So the only way to do this would be to have the Menu javascript write the html page inside every DIV based on the number of characters from the JSON, to include writing the data.

Right now the page exists, and when it is passed its data, populates the correct divs with the correct data from that JSON. So instead we would pull the data the menu would find a character node in the JSON, write the webpage in the DIV that button controls visiblility to include the data from the JSON.

Then loop and repeat for every character in the json

I feel like this is going to make the update that happens every 5 seconds look terrible instead of seamless like it is now. But if that is the only way since we can’t embed,iframe, or object then I guess it’s time to rewrite again.

You mean object as in HTML object tag ?

Yes, its the only thing that Ihaven’t tried yet, both iframes and embeds show me the frowny face. So I’m assuming that is because twitch says no you can’t do that. So before I go back to local test just to update one line zip reupload and test again I wanted to verify that objects will also not work.

IE this inside my loop

charList.innerHTML = charList.innerHTML.concat(`<button id="player${charCount}" class="playerButton"></button>`);
                            sheetList.innerHTML = sheetList.innerHTML.concat(`<div id="player${charCount}sheet" class="charsheet">
                            <iframe id="player${charCount}frame" class="charframe" type="text/html" data="./charsheet/charsheet.html?p=${charCount}">

Then yes that is correct. You cannot fetch and embed a raw HTML page/file from another place.

You’d have to do a Javascript Fetch of something that describes the content and build the content dynamically.

You would potentially do

                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    'x-extension-jwt': window.Twitch.ext.viewer.sessionToken
        ).then(response => response.json()
        ).then(data => {
            // use data to populate a template or build whatever

Yeah you can’t do that you’d have to build the display internally not include it via iframes/objects/othermeans

2.7 You must not inject directly into the DOM any data obtained dynamically over AJAX without first validating and processing that data.

It would also violate 2.7

2.2 Extensions may not use iframes.

and of course 2.2

2.8 All front-end HTML, CSS, and Javascript files used by your Extension must be included in the zip file for your assets. You should not include extraneous files or code not used by your extension.

and perhaps 2.8

Dang I was hoping since the page is from inside the extension that would work.

But also that is the processed data. That just creates the DOM for the number of characters taht exist, but any data is put in with innerText.

Edit after your edit:
The file is in the zip.

Well you are creating an iFrame to load pregenerated HTML inside your extension.

So since it’s all static, you can use CSS visiblity switches to “navigate” instead.

That is already how I do it, the buttons control the div visibility that the iframes lived in.

However the data inside the page (innerText) is not static, that updates and we check every 5 seconds (less if the extension menu is closed) and update the data accordingly

Then from what you wrote ./charsheet/charsheet.html?p=${charCount} doesn’t update since theres no mecahnsim to revise static HTML inside an extension.

And if this internal HTML is running it’s own JS to fetch offsite JSON to build the page with, you are over complicated by trying to use iFrames. You can just dynamically write instead, to the HTML you already have, not an embedded page

Either way: you can do what you are trying to do, but you can’t do it the way you are trying to do it

So let me explain this a bit better so you can understand the logic flow.

Menu pulls the data from the server, it takes that data to build the buttons, Divs, etc.

This menu also pulls from the server for any updates. Upon pulling it checks if the data changed. If it didn’t it does nothing, if it did, it then splits that json into the individual character records that it feeds to the (currently) embeds via a message.

the charactersheet\charsheet.html exists as the framework where all the data resides on top of a charactersheet png. The charsheet.js is listening for the message. Once it gets the message it then pulls the json data fed to it by menu and checks if it is different than what is currently has, if it isn’t then it does nothing, if it did change it then goes through and updates the data in the page.


function writeHP(hp) {
    if ('total' in hp) {
        document.getElementById('maxhp').innerText =;
        var maxHP =;
    else {
        document.getElementById('maxhp').innerText = "0";
        var maxHP = 0;

    if ('wounds' in hp) {
        var wounds = hp.wounds.value;
    else {
        var wounds = 0;

    document.getElementById('currenthp').innerText = (maxHP - wounds).toString();

So main pulls, then doles out the individual character data to the pages. So the charsheets don’t fetch anything, only the menu does, and feeds the charsheets.

And as you’ve found you cannot do using this method.

You cannot invoke the framework, via “iframe trigger” which is your current method.

These would need to be in the main HTML not loaded secondarily

Which is what I do in my character sheet extension.

So everything needs to be in the main HTML

Yeah I’m tracking. I’ll have to decide how I want to organize this now. If I’m lucky i can just copy paste the current html from charsheet and let menu write it out.

Whelp time for 0.9.2 I guess.