Turbo Frames with Browser Destination/URL Replacement

I have been working on trying to implement an “Application Shell” with navigation on the left and a search bar at the top. I want to have the search query “persist” between page navigation and so I used a Turbo Frame to do exactly that with a data-turbo-frame on the urls outside of the shell for the search results. This works exceptionally well, however it does not change the browser destination/URL.

The code looks a little something like this:

<div class="application_shell">
     <div class="search_component" >
     </div>

     <%= turbo_frame_tag "inner_shell" do %>
        <%= yield %>
     <%end%>
</div>

I was wondering could this functionality be added to Turbo/Hotwire or is there a far easier way that I am missing with the current version.

1 Like

This will be a dope feature to have. I am using streams for this, but it requires some effort to make it work for layouts like this.

Lets see if there is any way or if it can be supported in the future. Something like the following.

<turbo-frame id="content" navigates="_top">
</turbo-frame>
1 Like

Are you effectively making all the routes for the navigation just respond as a turbo_stream using the replace action? I never thought of doing that and its actually quite a nice solution, just annoying having to change a lot more routes to use this. Might give that a go to get it properly working!

Another option I thought of is by using the event turbo:before-stream-render and doing some javascript history and URL changes but that may get messy.

No, <turbo-frame> is its own scoped navigation context and won’t ever change the URL of the page. That’s what Turbo Drive visits are for.

But won’t this reload the whole page and thus make a “persisted” layout such as a search bar, lose its typed text/results upon a Turbo Drive visit?

You can use the data-turbo-permanent attribute to persist elements from one visit to another. There’s a section about this in the Handbook: https://turbo.hotwire.dev/handbook/building#persisting-elements-across-page-loads

1 Like

Oh of course! This was present in Turbolinks anyway! Thanks for the help

Turbo visits reset the window scroll though. I had a very specific use case where I have a search form (GET) on my page that is triggered via checkbox clicks through stimulus, I want each new search to be registered in the browser history for better navigation.

Turbo visits work but reset my scroll which is not convenient, restoring scroll after a visit is a bit tedious and not necessarily reliable, so I ended up implementing a stimulus controller that would update the navigation with the frame navigation : https://gist.github.com/Intrepidd/ac68cb7dfd17d422374807efb6bf2f42

Maybe this a terrible idea, let me know :slight_smile:

1 Like

You use the GET as a strategy to detect the turbo-frame event right ( the get method updates the src attribute ) ? … I wish there was a turbo-frame:load event or something like that, it would be nice

You use the GET as a strategy to detect the turbo-frame event right ( the get method updates the src attribute ) ? … I wish there was a turbo-frame:load event or something like that, it would be nice

1 Like

Hey folks, I just opened a PR that enables updating URLs on frame navigation (links and form submissions) and Turbo Stream responses: Optionally update URLs on Frame navigation and stream responses by bfitch · Pull Request #167 · hotwired/turbo · GitHub

Hiya – I can see the solution here states to use data-turbo-permanent, but what are you actually attaching data-turbo-permanent to to persist the url…?