-
Notifications
You must be signed in to change notification settings - Fork 429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Push state and updating URLs with Turbo Frames #50
Comments
Considering the example of a video player whose playback is uninterrupted during navigation: Would marking the |
It doesn't. The iframe visibly refreshes in the dom and the video loses its progress. The end result is the same with the following 3 combinations when using drive without frames:
This behavior also happens with Turbolinks 5 btw. I think it's just related to the spec of iframes. There's a 17 year old bug report on this at https://bugzilla.mozilla.org/show_bug.cgi?id=254144. It's marked invalid due to the nature of iframes. |
@nickjj I just ran into this use case as well. I’m currently wiring up a list -> details view (consisting of a sidebar and a main content area) and I’d love to change the URL from the index view I would be great if we could specify that a link with a |
I would also be interested in having Turbo Frames work similar to the "Target" feature of htmx or unpoly . With Turbo always replacing the complete body the "illusion" of using a SPA will sometimes be lost, especially if there are images on a page that do not change between sites but will flicker due to Turbo replacing the HTML. |
FWIW I accomplished it with the following stimulus controller using Mutation Observer. https://gist.github.com/Intrepidd/ac68cb7dfd17d422374807efb6bf2f42 |
@bfitch I was thinking about this recently and I think that would be the way to go too. Because if you had a drop down menu loading in a frame you wouldn't want a URL change for that, so the URL push target likely needs to be an optional attribute. Even in the hotwire example screencast it would be reasonable to want to set the URL when you edit a resource. This is seen at the 3 minute mark https://www.youtube.com/watch?t=180&v=eKY-QES1XQQ. Notice how the URL doesn't get updated when clicking edit, but a few seconds before when the content wasn't loading in a frame it did.
@Intrepidd do you have a usage example to go with the controller? Or is it only a matter of attaching a |
You need to connect the controller directly on the frame and it should work.
|
Hi all, I've successfully implemented @Intrepidd's Turbo Frames Navigation Controller in a Shopify embedded proxy app. So that's great and the whole principle work. Would be awesome to have this as some kind of data-attribute in Turbo itself. One other thought I had. I basically have used this method now to embed a Turbo app inside another website. Essentially I only have the need for a single top level Turbo Frame. So another way of solving my use case would be to set a top level container other than |
I would love this also. We have a, sort of, "wizard" on the main content part of the page. On the sidebar, we have a lazy-loaded frame. If we do nothing, each time we click through the wizard, the whole page reloads (including the lazy frame, which is annoying). We thought to add a frame around the wizard... which works, except that we want the option to change the URL on links inside that frame :). Thanks! |
Maybe we could have a concept of "main frame" or "navigation frame" that would be behaving like target _top url-wise but would not refresh the whole page |
I think having the ability to mark a Frame as |
I was also able to get the @Intrepidd Turbo Frames Navigation Controller working. It works nicely to push/pop state. The challenge for me is when I load into a targeted Turbo frame (e.g. Frame A) content from url 1 and then content from url 2, hitting back should load url 1 into Frame A, not load the url as an entire page load. We also need a way to maintain knowledge of what the original target was and then load into that frame. I could capture the frame id in the event state, but don't have a way to target the url into the frame. |
Without built-in support, is it possible to achieve this behavior without using a turbo-frame at all by using Turbo events: https://turbo.hotwire.dev/reference/events let mainFrame = null
addEventListener("turbo:click", ({ target }) => {
// [data-main-frame] is an arbitrary attribute name
mainFrame = target.closest("[data-main-frame][id]")
})
addEventListener("turbo:before-render", ({ detail }) => {
if (mainFrame?.id) {
const newMainFrame = detail.newBody.querySelector("#" + mainFrame.id)
if (newMainFrame) {
mainFrame.innerHTML = newMainFrame.innerHTML // replace the NEW frame's HTML with the OLD frame's HTML
detail.newBody.innerHTML = document.body.innerHTML // replace the NEW page's HTML with the OLD page's HTML
}
}
mainFrame = null
}) This will carry forward the rest of the page's HTML into a new Visit, while preserving the NEW content served within the "main frame". This is pseudo code, but the concept itself might be viable. |
Would you mind giving it a whirl with an |
Here's a reimplementation of my controller to reproduce this behaviour with turbo beta 4 Now that the Location API is being used rather than the previous internal API, we can use the turbo navigator and have a much smaller controller. I'm also using stimulus-use to facilitate the mutation observer code, but you can mix and match with my previous implementation if you don't want to use stimulus-use. https://gist.github.com/Intrepidd/bb1ffc5944a5c1ec3a9f5582753c4b67 |
@Intrepidd Works like a charm, thank you! 🙏🏻 It would definitely be useful if this was part of Turbo, as I wouldn't be able to figure it out by myself. |
A gotcha with @Intrepidd solution: In my case, I tried to optimise and respond just with the turbo-frame if I detect the appropriate header set by Hotwire. For faster user experience, I also set a short expiration header: expires_in 20.minutes
if request.headers["turbo-frame"] == "movie_feed"
render "movies_feed_turbo_frame"
else
render :index
end Navigating into the frame works perfectly, but once you navigate to another page and hit the back button, Hotwire will replace the whole Even if you optimisation is simpler than mine (e.g. just This doesn't happen if you don't set expiration headers of course. Agree with @janko it would be great to have the whole use case supported by Turbo out of the box, as it allows you to efficiently patch the page with smaller updates while updating user's history for greater usability. Example use case: a feed with filters that just updates the feed results and URL, while keeping the rest of the page untouched as you apply various filters. |
I believe the best way to fix the back button problem with @Intrepidd's controller lies in this line:
We should push not only the URL to the state but the frame as well. And Turbo should respect that param as well as respects the data-turbo-frame attribute on links and buttons Having something like this would be cool:
|
I tried to hack an updated controller that handles history itself, and have the Back button working: https://gist.github.com/Kukunin/5033345db6da9d2edc002dc3f39702ac. I was surprised how isolated turbo frames are implemented in Turbo, there is no way to pass turbo-frame to Turbo.visit nor to Navigator, and how turbo-frame works is via LinkInterceptor that just changes frame's src attribute. |
The solution from @seanpdoyle is interesting too. I believe it won't work because of this line: Just checked, |
+1 this feature would be invaluable |
@Kukunin, I've tried your solution, and it works ok, but just for one history back, if I try to back twice, it does not change the page. |
@michelson you're right, thanks for the reporting. I'll update my gist with the fix soon |
@michelson found a bug, where the observer pushed a new state every time the back button clicked. Fixed in my gist |
@Kukunin thanks for let me know, I can confirm that is working flawlessly :) |
@Kukunin it seems that the solution has an issue when navigating from history. to reproduce:
result:
I think it should make a navigator.history.push as a fallback , what you think ? |
@michelson oh, that might be complicated since the controller needs to mount/demount itself. It's out of the scope of my usage (I have the frame on every page), but I could take a look if you can create a reproducible case for me (as a Github repo). Thank you for testing, it's valuable for community |
Hi @Kukunin, thanks for taking your time to take a look, here is the example repo https://github.com/michelson/history-turbo-rails-example, let me know if that's what you need, I hope you find it useful to debug the problem. demo: Screen.Cast.2021-07-07.at.7.38.09.PM.mp4I've tried the following, kinda works, but after the
|
@dhh Is there a plan on solving these url and history issues out of the box? To me the idea of providing a parameters to the link or form to define if it should replace the url and/or push to history sound promissing. Would be great to know your plans on this. So we know if we should build our own workaround or wait (and if needed/wanted help) for an implementation in turbo. |
I'd like to see Turbo offer more direct controls, but there's not a final proposal ready to go. There won't be anything in the box for 7.0. So I'd say go right ahead and experiment in your own apps. That's a better way to figure out what an official version should look like anyway. |
hotwired#50 hotwired#361 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's histroy push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
hotwired#50 hotwired#361 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's histroy push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[dat-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
hotwired#50 hotwired#361 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's histroy push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[dat-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
hotwired#50 hotwired#361 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's histroy push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[dat-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Closes hotwired#50 Closes hotwired#361 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's histroy push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[dat-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Closes hotwired#50 Closes hotwired#361 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's histroy push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[dat-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Closes hotwired#50 Closes hotwired#361 Closes hotwired#167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Closes hotwired#50 Closes hotwired#361 Closes hotwired#167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Closes hotwired#50 Closes hotwired#361 Closes hotwired#167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Closes hotwired#50 Closes hotwired#361 Closes hotwired#167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Hi, the following workaround works pretty well for me: document.addEventListener('turbo:frame-render', async e => {
if (['main', '_top'].includes(e.target.id))
history.pushState(history.state, '', await e.detail.fetchResponse.location)
})
window.addEventListener('popstate', () => Turbo.visit(document.location)) |
Closes hotwired#50 Closes hotwired#361 Closes hotwired#167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
Closes hotwired#50 Closes hotwired#361 Closes hotwired#167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
What's the current state of this? I really like the idea of a more generic approach that's baked in already, similar to how we can opt-in/out of using turbo for individual links/blocks. |
Closes hotwired#50 Closes hotwired#361 Closes hotwired#167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits
* Add `linkClickIntercepted` to FrameElementDelegate Expand the `FrameElementDelegate` interface to include a `linkClickIntercepted` to match its existing `formSubmissionIntercepted`, then replace a manual `setAttribute` and `src` assignment with a delegation to the `FrameElementDelegate` instance. * Push history state from frame navigations Closes #50 Closes #361 Closes #167 --- Extend of built-in support for `<a>` elements with [data-turbo-action][] (with `"replace"` or `"advance"`) to also encompass `<turbo-frame>` navigations. Account for the combination of of `[data-turbo-frame]` and `[data-turbo-action]` to navigate the target `<turbo-frame>` _and_ navigate the page's history push state, supporting: * `turbo-frame[data-turbo-action="..."]` * `turbo-frame a[data-turbo-action="..."]` * `a[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."][data-turbo-action="..."]` * `form[data-turbo-frame="..."] button[data-turbo-action="..."]` * `form button[data-turbo-frame="..."][data-turbo-action="..."]` Whenever a Turbo Frame response is loaded that was initiated from one of those submitters, forms, anchors, or turbo-frames annotated with a `[data-turbo-action]`, the subsequent firing `turbo:frame-render` event will create a `Visit` instance that will skip rendering, won't result in a network request, and will instead only update the snapshot cache and history. [data-turbo-action]: https://turbo.hotwired.dev/handbook/drive#application-visits * Extract `getAttribute` utility function For cases where we need to find an attribute value from a collection of elements, use `getAttribute` instead of a long chain of `||` and `?` operators.
This issue doesn't mention, but there's easy standalone solution: |
@xpopov data-turbo-action="advance" does solves the forward navigation issue, but its showing weird behavior when I click back button in the browser. I am new to the rails ecosystem, honestly these little things are pretty annoying and it's really hard to figure out what's happening. I wish these would work out of box @dhh just like rails. |
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:
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.
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?
The text was updated successfully, but these errors were encountered: