Turbo-stream with update URL

Hello
I have searchbar, filters and table
I need search items by using searchbar and filters togehter
I implemented this functionality using turbo-streams, but my URL doesn’t update. And I want to make it so that the user can copy and paste the link, keeping the search and filter options.

I did this with turbo_frame, but I need to update the two partials, the search string and the filters. Is there some analogue of turbo_action: “Advanced” for turbo-stream?

1 Like

You can still use turbo-stream inside frames.

<turbo-frame>
    <turbo-stream action="replace" />
    <turbo-stream action="replace" />
</turbo-frame>

Other than that. I’m afraid you’re going to have to use JavaScript and update the URL programatically. Using the URL and URLSearchParams APIs.

2 Likes

Here is a stimulus controller i’m using that works with streams.

export default class extends Controller {
  static values = {
    url: String,
    labelFilter: {
      type: Array,
      default: [],
    },
  }
  applyLabelFilter(e) {
    this.labelFilterValue = [...this.labelFilterValue, e.target.dataset.filter]
    this.getFilteredResults()
  }

  async getFilteredResults() {
    const url = new URL(this.urlValue)
  
    this.labelFilterValue.forEach((filter) => {
      url.searchParams.append("label[]", filter)
    })
  
    await get(url.toString(), {
      responseKind: "turbo-stream",
    })
  
    this.changeBrowserUrl()
  }
  changeBrowserUrl() {
    const url = new URL(window.location.href.split("?")[0])
  
    this.labelFilterValue.forEach((filter) => {
      url.searchParams.append("label[]", filter)
    })
  
    history.pushState({}, null, url.toString())
    Turbo.navigator.history.replace(url.toString())
  }
}

When Each tag(label) is clicked it calls applyLabelFilter Something like

<div data-controller="filters">
   <button data-filter="age" data-action="filters#filter">age</button>
<div>

Is this still the case? No way to update URL from TurboStream natively?

Wondering the same thing… I have a form that submits and I want it to update two elements, so I can’t use turbo-frames, since those can only update a single element (apparently? I’m not sure why this is the case if my response contains two frames why can’t it update two frames in my body?), but when I try to switch it to use turbo stream elements instead; the two elements DO get updated as expected, but now my URL isn’t changing.

I’ve tried wrapping the form in a turbo frame (haml):

= turbo_frame_tag :order, data: {turbo_action: "advance"} do

And using the turbo stream elements in the response to target this element:

= turbo_stream.replace :order do
  = render partial: "orders/form", locals: {order: @order}

This does work, but it’s not updating the page URL like I might expect :confused:

Take a look at the Turbo Power Browser Actions and Turbo Actions I’m not one hundred percent sure that this will suit you, but who knows :slight_smile:.