-
Notifications
You must be signed in to change notification settings - Fork 435
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
Turbo frame history not navigating properly w/ back button after upgrading from 7 to 8 #1241
Comments
I'm experiencing the same issue, after the upgrade, a link inside a turbo frame is updating the URL correctly but when I use the back button, it only shows the current snapshot. |
I tried reproducing and could not. Is there a simple code example that reproduces this? |
Hi @tleish! Sorry for the delay. I should have time this weekend to make a simple app to demo the issue. |
I've run into this as well. A simple html page with turbo_frame and a link can trigger this. Controller action <%= turbo_frame_tag 'page' do %>
<%= render 'users', users: @users %>
<p>
<%= link_to_prev_page @users, '< Previous Page', data: { turbo_frame: 'page', turbo_action: 'advance' } %>
<%= link_to_next_page @users, 'Next Page >', data: { turbo_frame: 'page', turbo_action: 'advance' } %>
</p>
<% end %> (prev/next links are from kaminari). Loading index, clicking "Next", then Browser's back button triggers this issue. The page content is not being refreshed. |
I just tested again and like @pjg, when I use: Turbo.visit(url.toString(), {frame: 'search-results', action: 'advance'}); The URL is updated but when I hit the back button, I don't see the previous page. it only happens with the initial call, if I use |
Ok, I was able to reproduce this by moving the links outside the turbo-frame, where it did work where links were within the turbo-frame. |
I am not able reproduce this, even by moving the links outside the frame. I was looking primarily at this page after running Does this only happen in rails? Do the URLs have to have query strings? Trying to figure out how you break this. |
Tried my local test again. Realized it had nothing to do with links inside or outside the For example: <turbo-frame id="results">
Does not cache and show on Restoration Visit
</turbo-frame> <turbo-frame id="results">
<div>Caches and shows on Restoration Visit</div>
</turbo-frame> So, I'm still unable to reproduce the original issue. |
Interesting. That sounds like a different bug. I wonder why the HTML tags affect the behavior. |
I'm not sure the turbo-frame with text only not rendering on restoration visits is a bug. I believe turbo uses cloneNode to cache html. If the frame has no nodes to cache (text only), then it doesn't cache it. |
FYI, one (failed) attempt to reproduce the issue: https://github.com/tleish/turbo-frame-history Perhaps others can use this as a starting point to reproduce the issue. |
Note: I tested this on MacOS Chrome, Firefox and Safari. Perhaps it's a specific OS and/or browser? |
I've created a minimal reproducible testcase. I'm using Rails. Here's the repo: https://github.com/pjg/turbo-frame-bug Steps to reproduce: bundle install
bin/rails server Navigate to http://localhost:3000 Click "Next page". Click Back browser button. On my end (MacOS; Chrome, Safari, Firefox) when I click Back page content doesn't refresh. It stays the same, while it should display the previous page. NOTE: It starts working again if I click Next Page/Previous Page a couple of times. |
Here's a more minimal way to reproduce (outside of rails):
firstpage.html<!DOCTYPE html>
<html>
<head>
<title>Frame advance bug</title>
<script data-turbo-track="reload">
</script>
<script src="turbo.es2017-umd.js"></script>
</head>
<body>
<h1>My Page</h1>
<turbo-frame id="page">
<p>First page</p>
</turbo-frame>
<p>
<a
data-turbo-frame="page"
data-turbo-action="advance"
href="/nextpage.html"
>Next page</a
>
</p>
</body>
</html> nextpage.html<turbo-frame id="page">
<p>Next page</p>
</turbo-frame> The issue seems to be the presence of the |
I do not find it to be true. In my regular app I'm running with |
Have you viewed source on the page and confirmed that there is no data-turbo-track="reload" anywhere in your HEAD? I ask because I'm not sure it's easily removed from a boilerplate rails app. |
You're right. Rails adds The source is here: https://github.com/rails/importmap-rails/blob/0a6330133b75a72d7c5d07fe87c2fce50d76b997/app/helpers/importmap/importmap_tags_helper.rb#L15 -- I don't think it can be "turned off". |
Yep. That's the issue. Well, the issue is in Turbo but yeah that's why you can't workaround the issue easily. |
@tpaulshippy - I think you found the cause. Testing out @pjg github project, I saw it reproduced. The original page requesting includes several elements with app/controllers/turbo/frames/frame_request.rb # turbo-rails-2.0.5/app/controllers/turbo/frames/frame_request.rb
# The layout used is <tt>turbo_rails/frame.html.erb</tt>. If there's a need to customize this layout, an application can
# supply its own (such as <tt>app/views/layouts/turbo_rails/frame.html.erb</tt>) which will be used instead.
layout -> { "turbo_rails/frame" if turbo_frame_request? } From the above comment you can replace the minimal app/views/layouts/turbo_rails/frame.html.erb with your own. Testing this out I added <html>
<head>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>
<body>
<%= yield %>
</body>
</html> After doing this workaround, turbo-frame Restoration Visits (back) work as expected. I don't see this as the "solution", just a temporary workaround until the actual problem is fixed. |
Will this also make sure to trigger a reload of the page if there has been a new deploy and the asset files has changed? If so, it maybe a smart thing to do anyway? |
Yes @jonh-favo Looks like this issue started to break here: ed72ba1 It doesn't seem like the frame should be required to have all the same tags (with turbo-track=reload) in head as the hosting page for the back button to work. But that seems to be what's happening. |
I discovered that I also need to add all meta tags that configures turbo in that turbo_rails/frame.html.erb layout, and I needed to add csrf_meta_tag. Otherwise all requests made by turbo afterwards were missing the the x-csrf-token header and reverted to default turbo behavior. For instance I've disabled the prefetch functionality in the application.html.erb layout, but after a single turbo request that updated a frame it was suddenly enabled again. |
I also ran into this just today, can confirm @tleish's workaround fixes it. |
After the changes made in [@hotwired/turbo#867][] and changes made in [@hotwired/turbo-rails#428][] (the canonical server-side implementation), Turbo expects full HTML documents in response to requests with `Turbo-Frame:` headers. Prior to this commit, the `FrameController` compensated for missing pieces of an HTML document by taking an HTML "snapshot" of the current page through the `<html>` element's [outerHTML][]. This commit changes the `fetchResponseLoaded` callback to read the `responseHTML` directly from the `FetchResponse`, since that will be a fully formed HTML document in Turbo v7.3.0 and later. To support that change, this commit also updates various `src/test/fixtures` files to render fully-formed HTML documents. [@hotwired/turbo#867]: #867 [@hotwired/turbo-rails#428]: hotwired/turbo-rails#428 [outerHTML]: https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
Just noting this for @tleish, primarily in case it's relevant to the fix in the merged PR: I discovered that the above workaround breaks pages that try to force reload a new page via It looks like adding <html>
<head>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag "application", "custom", "actiontext", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html> |
Hi, I have tried doing the solution above by replacing the frame.html.erd but it's still not working. When clicking the back button with or without this solution, the back button seems to work 1 time out of 10 but I am not sure what I did different to make it work. Also I noticed that when it works, sometimes its getting the page from the cache but sometimes its doing a full page reload instead. Did someone still has the same problem? |
hey @cavenk, the above workarounds should work - for turbo 8, as a recap, the full workaround I'm currently using in production for the past 6 weeks or so is: in <html>
<head>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag "application", "custom", "actiontext", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html> ymmv - but the problem you're mentioned (1/10 times it works) does sound similar to what I was experiencing - the bacl bittpm would sometimes be successful depending on if a turbo frame action had previously triggered or not. |
Hi, I also run into this problem and tried the layout patch without success. If I do a single navigation, the back button does nothing (except breaking things mostly because of outdated CSRF). |
Context:
Application has a simple live search via form:
What's happening: Live search is working fine. When the form is submitted (automatically as a user types), the turbo frame is updated with the correct results and the URL displays the correct query parameters. However, when navigating with the back button the turbo frame does not navigate backwards, it only shows the most recent set of results (despite the url and associated query params appropriately changing backwards).
What should be happening: As the user navigates backwards the URL query params should change (which is happening) and the turbo frame should reflect the history from that point in time.
When did this start happening: This happened on Turbo 8.0.4. and Turbo Rails 2. If I revert to Turbo < 8 and Turbo Rails < 2, the behavior works as expected.
The text was updated successfully, but these errors were encountered: