例えば Hotwire の Turbo Frame を使って検索機能を作る場合、検索結果に検索パラメータを付与した固有の URL にしたくなります。通常だと Turbo Frame の切り替え時には URL は変化しません。標準でサポートする Proposal も出ていますが微妙な部分なので将来的にサポートされるかは分かりません。

とりあえず、シンプルなコードでも似たようなことは実現できるのでコードを紹介します。

サンプルコードは Article 一覧の status フィールドが 01 のものを検索し、結果を Turbo Frame で表示しています。URL は /aritlces?status=0/articles?status=1 を想定しています( JS が使えなくても検索できるようなインターフェイスに統一するのが良いと思います)。

Stimulus のコントローラでは検索用のフォームデータを取得し、QueryString に変換をします。それを Turbo が提供する navigator オブジェクトを使って history.push するだけです。

import { Controller } from 'stimulus';
import { navigator } from '@hotwired/turbo';

export default class extends Controller {
  static targets = [ 'input', 'form' ];

  search() {
    const queryString = new URLSearchParams(new FormData(this.formTarget)).toString();
    const url = location.origin + location.pathname + '?' + queryString;
    this.formTarget.dispatchEvent(new CustomEvent('submit', { bubbles: true }));
    navigator.history.push(new URL(url));
  }
}
<%= form_with(url: articles_path, method: :get, data: { turbo_frame: 'articles', controller: 'article', article_target: 'form' }) do |form| %>
  <%= form.radio_button :status, 0, data: { article_target: 'input', action: 'article#search' } %>
  <%= form.radio_button :status, 1, data: { article_target: 'input', action: 'article#search' } %>
<% end %>

<%= turbo_frame_tag "articles" do %>
  <% @articles.each do |article| %>
    <%= article.title %>
  <% end %>
<% end %>

シンプルですね。