hotwired / turbo

The speed of a single-page web application without having to write any JavaScript
https://turbo.hotwired.dev
MIT License
6.72k stars 428 forks source link

Push state and updating URLs with Turbo Frames #50

Closed nickjj closed 2 years ago

nickjj commented 3 years ago

Hi,

Let's say I wanted tabs on a page to be loaded in frames but I wanted each tab to have its own distinct URL. Currently it doesn't seem like this is possible out of the box because switching between frames doesn't update the URL.

Here's a real world use case of where I wanted to use Turbo Frames but ended up aborting the idea of it and going back to making a raw ajax request and then not rendering the layout of the page at the controller level when I detected it was an ajax request.

We all remember Railscasts right? Here's one of its pages: http://railscasts.com/episodes/416-form-objects?autoplay=true

The neat thing about this page is if you're playing a video, you can navigate between the show notes, comments and the other tabs without the video player stopping. Each tab also has its own unique URL so you can bookmark it and share it with others.

In Railscast's case I believe just using Turbo Drive and the permanent attribute would have been good enough to make this work because Ryan is using a native video player.

However, a lot of video services like Vimeo expect you to embed an iframe and iframes have a very unique characteristic in that as part of the spec if the underlying DOM of the iframe changes then the iframe gets reloaded which means the video watching experience gets interrupted (even when using the permanent attribute).

So that leaves us with at least 2 choices to get an uninterrupted video playback experience:

  1. Have each tab as its own controller but then manually set up some JS to make each link an ajax request and have Rails not render the layout at the controller level unless someone is directly accessing the URL.

  2. Use the new Turbo Frames feature (which works), but then the URL doesn't get updated.

Is there a way forward where push state could be added to Turbo Frames, or would that not make sense for the use case that frames is trying to tackle, and in the above case we should wire up a manual ajax call to have that desired effect?

seanpdoyle commented 3 years ago

Considering the example of a video player whose playback is uninterrupted during navigation:

Would marking the <iframe> or an ancestor with an [id] attribute and data-turbo-permanent help? If the player were permanent, the "tabs" wouldn't need to be frames, and could be full-on page navigations, and Turbo would manage the extraction and injection of the player element across visitations.

nickjj commented 3 years ago

Would marking the