Call render a turbo-stream template in a stimulus controller

Hi

I get a turbo-stream template back to my stimulus modal controller. The response looks as:

<turbo-stream action="append" target="flash_messages">
 <template>
  <!-- app/views/application/_flash_message.html.erb -->
  <div id="flash_messages">
    <div class="alert alert-notice">
      Action not authorized
    </div>
  </div>
 </template>
</turbo-stream>

I can fetch the flash_messages and append them to correct parent, but is that best way?

I have been looking for a way just call Turbo from my stimulus controller in browser and the let it handle the update for me, is that possible?

Best
Jens

You can use the Turbo.renderStreamMessage() method to handle the Turbo Stream updates from your Stimulus controllers.

Here’s a simple controller that makes a fetch request to the server, receives a stream response, and renders that stream into the document.

import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="replace"
export default class extends Controller {
  swap() {
    fetch("/test/replace", {
      method: "POST",
      headers: {
        Accept: "text/vnd.turbo-stream.html",
        "X-CSRF-Token": this.getCsrfToken()
      }
    })
      .then(r => r.text())
      .then(html => Turbo.renderStreamMessage(html)) // <turbo-stream action="replace"> ...</turbo-stream>
  }

  getCsrfToken() {
    return document.querySelector('meta[name="csrf-token"]').content;
  }
}

This is what Turbo does behind the scenes.

Hope that helps!

1 Like