Finally Understanding <turbo-stream>

This post was very useful but it still took me a while to understand how to set this up on the server side. Here is the beginner intro to this topic, I am using FastAPI and Python but I’ll try to stay closer to the generic html/http topics.

On the Client

You ship any element to the client with a specific id. This is an element that you plan to mutate with turbo-streams, for instance we have this h3 element:

<h3 id="mutandis">Title to be replaced!</h3>

You also ship a button or a submit form. Why? Well we want to click and get a post response from the server.

<form action="/some_server_endpoint" method="post">
    <button class="button ">Test Streams</button>
</form>

On the Server

The server should accept post requests on /some_server_endpoint url (of course any url will work). Now here is the kick, you want the server to send back response headers like so:

 accept: text/vnd.turbo-stream.html 
 content-length: 137 
 content-type: text/vnd.turbo-stream.html; charset=utf-8 
 date: Mon,25 Jan 2021 16:25:25 GMT 
 server: uvicorn 

Two things are critical here:

  • That you set the media_type to text/vnd.turbo-stream.html
  • That you set the header accept to be equal to text/vnd.turbo-stream.html

Here below an implementation on the server side in Python and FastAPI

@router.post("/some_server_endpoint", response_class=HTMLResponse)
async def testing(response: Response, frame_name: str = ""):
    #Build the html turbo-streams here
    return HTMLResponse(
        content= #streams html
        media_type="text/vnd.turbo-stream.html",
        headers={"Accept": "text/vnd.turbo-stream.html"},
    )

The html content of the response should look like this:

<turbo-stream action="replace" id="stream" target="mutandis">
  <template>
    <h3 id="mutandis">Turbo Stream to the rescue!</h3>
  </template>
</turbo-stream>

Note the target mutandis is the same as the id of the h3 element we want to replace in the dom. Turbo will mutate your dom element on the client like so:

<h3 id="mutandis">Turbo Stream to the rescue!</h3>

Now most important of all, why should we do this?

Replacing multiple dom elements with 1 response

We can have these on the client

<h3 id="mutandis1">Title to be replaced!</h3>
<h3 id="mutandis2">Title to be replaced!</h3>

And with just 1 server response like below we can update both elements:

<turbo-stream action="replace" id="stream" target="mutandis1">
  <template>
    <h3 id="mutandis1">Turbo Stream!</h3>
  </template>
</turbo-stream>
<turbo-stream action="replace" id="stream" target="mutandis2">
  <template>
    <h3 id="mutandis2">Turbo Stream!</h3>
  </template>
</turbo-stream>
3 Likes