JS <script> loaded within <turbo-frame id="x" src="/y"> runs locally, fails production

Update: I understand how to use FrameElement now

const myFrame = getElementById(‘frameID’);
myFrame.loaded.then(()=>{ … });

I’m still curious why hardcoded < script> or js file embedded within a turbo-frame runs locally, but not on production server.

I’m a bit confused on the use of Turbo events and FrameElement for what I’m trying to do. How do I run JS on DOM elements created after content within a turbo-frame has fully loaded via the src attribute? The HTML within the turbo-frame is a feed generated after receiving JSON data from a 3rd party API, and it takes quite a bit of time.

In the sample code below, ‘loaded’ runs locally, and does not run at all in production. ‘turbo:load’ neither runs locally or on production.

<%= turbo_frame_tag “listings” do %>
< div class=“listings_feed” >
<%= render partial: ‘feed’, locals: {listings: @listings } %>
< /div>
< script>
console.log(‘loaded’);
document.addEventListener(“turbo:load”, function() {
console.log(‘turbo:load’);
});
< /script>
<% end %>

If I run addEventListener(“turbo:load”, …) within a separate JS file for my page, naturally, that gets run after the page loads, not after the turbo-frame populates its contents.

Alternative, I have been trying to understand the use of FrameElement (https://turbo.hotwire.dev/reference/frames#properties), but can’t figure out how to access the FrameElement instance. Are there examples anywhere of how to use this? How do I make use of FrameElement.loaded for my purposes?

1 Like

This worked for me with vanilla JS (where #content-blocks is the turbo-frame ID)

document.querySelector("#content-blocks").loaded.then(() => {
  ...
  })
1 Like