Skip to content

How can I execute JavaScript when a new Turbo Frame is loaded

I am using Turbo Frames in my Rails app and have, on every page

<turbo-frame id="messagesFrame" src="/chats">

This loads in fine, and when a link is clicked replaces the frame as expected. In this frame I have set overflow-y: scroll, creating a scrollable frame on the page. Every time a new page is loaded in the frame, I want it to scroll to the bottom. How can I achieve this? Ideally with vanilla JavaScript.


You could do this several ways.

Turbo should fire a turbo:before-fetch-request and turbo:before-fetch-response on the document when lazy loaded frames, or links that trigger a frame reload.

You could do something like:

document.addEventListener("turbo:before-fetch-response", function (e) {
  let frame = document.getElementById("messagesFrame");
  if (frame.complete) {
   frame.scrollTo(0, frame.scrollHeight)
  } else {
    frame.loaded.then(() => frame.scrollTo(0, frame.scrollHeight))

Sources: Turbo events =>

Frame.complete and Frame.loaded =>

I suggest the above method because you specified vanilla Javascript. The recommended way for most Turbo related things is to use StimulusJS.

You could write a Stimulus ( controller that you attach to an element in the body that shows inside the TurboFrame, and in the connect method, do the same.

That way, whenever the content inside the frame is refreshed the Stimulus controller will run, and you don’t have to worry about the order of the events being fired.