html content renders in Iframe but not in div

I want to create a Vue app which renders another vue app. This is achieved by creating an Express fileserver serving the index.html of that app to render.

I created a file with a div container and fetch the app to render from my file server.

<template>
  <div id="customAppContainer"></div>
</template>

<script>
export default {
  async mounted() {
    const fullRoute = this.$router.currentRoute.fullPath;
    const routeSegments = fullRoute.split("/");
    const appsIndex = routeSegments.indexOf("apps");
    const appKey = routeSegments[appsIndex + 1]; // The name of the app

    const response = await fetch(`http://localhost:3000/apps/${appKey}`); // fetch the index.html
    const html = await response.text(); // convert the filecontent to a string
    document.getElementById("customAppContainer").innerHTML = html; // load the file content into the div
  }
};
</script>

By doing so I get a blank page and no console error. But the DOM shows that the html string created valid DOM elements in that div container. When I change the div to an iframe and assign the fetch url as a src of that iframe this iframe is able to render the Vue app / index.html file correctly.

For debugging purposes, this is the HTML string I get from the fileserver:

<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>my custom app</title><link href=/js/app.5eb51f47.js rel=preload as=script><link href=/js/chunk-vendors.c3422c1d.js rel=preload as=script></head><body><noscript><strong>We're sorry but my custom app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=customApp></div><script src=/js/chunk-vendors.c3422c1d.js></script><script src=/js/app.5eb51f47.js></script></body></html>

How can I avoid that iframe and load the html content into the div?


Solution 1:

I finally got it working by embedding an object into the div container and assigning it's data to the src url.

<template>
  <div id="customAppContainer"></div>
</template>

<script>
export default {
  async mounted() {
    const fullRoute = this.$router.currentRoute.fullPath;
    const routeSegments = fullRoute.split("/");
    const appsIndex = routeSegments.indexOf("apps");
    const appKey = routeSegments[appsIndex + 1];

    document.getElementById(
      "customAppContainer"
    ).innerHTML = `<object data="http://localhost:3000/apps/${appKey}"></object>`;
  }
};
</script>