Open charlesobrien opened 7 months ago
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. The weird part is that its only for the first link inside the turbo frame, if I click on another link afterwards, the history and the snapshots seem to work as expected
I tried reproducing and could not. Is there a simple code example that reproduces this?
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 index
and corresponding index.html.erb:
<%= 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 Turbo.visit
a second time and hit the back button, it works as expected.
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 npm start
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 turbo-frame
, but rather IF the content inside the turbo-frame had any HTML, which I don't necessarily think is a bug.
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 able to reproduce that issue either @tleish
Got it. If the original frame content has just plain text, the back button will not restore it. Weird. Are you going to open another issue for that one? @tleish
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):
Create the following two html files:
<!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>
<turbo-frame id="page">
<p>Next page</p>
</turbo-frame>
The issue seems to be the presence of the data-turbo-track="reload"
attribute on any valid tag in the HEAD. If you remove that attribute, the issue goes away. But if you put it on any tag (I tried it on <title>
, <meta>
, and <script>
), you see the issue.
The issue seems to be the presence of the data-turbo-track="reload" attribute on any valid tag in the HEAD. If you remove that attribute, the issue goes away.
I do not find it to be true. In my regular app I'm running with data-turbo-track: ''
(empty string). If I remove data-turbo-track
from my minimal Rails example app, I can still reproduce the issue.
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 data-turbo-track: "reload"
for importmaps.
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 data-turbo-track
, but the HTML from turbo-frame response has an empty <head>
. This is because the turbo-rails gem includes the following logic:
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 addedapp/views/layouts/turbo_rails/frame.html.erb
to the project with tags that include data-turbo-track
(javascript_importmap_tags adds it). Note that I ignore title, meta and other tags that do not include data-turbo-track
.
<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: https://github.com/hotwired/turbo/commit/ed72ba16bc23dcccd88e0ab76ba72cfef82cd599
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.
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 <% turbo_page_requires_reload %>
or <meta "turbo-visit-control", content: "reload"</meta>
.
It looks like adding <%= yield :head %>
to the workaround fixes it, but I don't know turbo well enough to be confindent:
<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 app/views/layouts/turbo_rails/frame.html.erb
:
<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. It always fails if I try to go back to the very first page.
If I do a single navigation, the back button does nothing (except breaking things mostly because of outdated CSRF). If I navigate twice, then the back button works once.
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.