Thought: Being able to define the root element (defaults to Body)

Just had a random thought - I know that replacing the <body> content can cause some issues (such as with persistent iframe elements that reset when the DOM node is moved). As such, I wonder if there would be any merit to having Hotwire make the “root element” configurable? So, it could default to the <body> tag; but, would give people a chance to do something like:

<body>
    <section data-turbo-root-element>
        <!-- Rest of the app content. -->
    </section>

    <p>
        I am _outside_ the _automatic_ Hotwire content updates.
    </p>
</body>

This might create all kinds of other issues, I’m not sure. But, it just popped into my head.

Right now, I’m exploring a persisted video player in Hotwire. And, the only way I can get it to work (without using something like morphdom) is to inject the Turbo Frame in between the <head> and <body> tags:

This likely has its own set of issues (such as accessibility problems). But, if I could designate a “root content element” internally to the Body, I would have to hack something like this.

Again, there’s probably a lot more detail to consider, but I just wanted to share some perspective on where my head is at.

There’s a discussion around changing the render element in this pull request, among other things to fix iframes:

It’s quite interesting actually

As for the persisted video player maybe the data-turbo-permanent attribute could work?

Thanks, I’ll take a closer look at the discussion. The data-turbo-permanent approach works, so long as you’re not using an iframe. IFrames reload when you move them around in the DOM.

There’s this draft PR which would add <meta name="turbo-body" content="app">

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="turbo-body" content="app">
    <title>Drive (with custom body)</title>
    <script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
    <script src="/src/tests/fixtures/test.js"></script>
  </head>
  <body>
    <h1>Drive (with custom body)</h1>
    <div id="app">
      <div>
        <a id="drive" href="/src/tests/fixtures/drive_custom_body_2.html">Drive enabled link</a>
        <a id="mismatch" href="/src/tests/fixtures/drive_custom_body_3.html">Drive enabled link to page with mismatched custom body</a>
      </div>

      <p id="different-content">Drive 1</p>
    </div>
  </body>
</html>

And also this monkeypatch

1 Like

Very cool - at the very least it validates that my thought wasn’t crazy :smiley: I love how responsive the Hotwire community is. It seems that so many of the ideas that people bring up eventually make it into the framework.