-
Notifications
You must be signed in to change notification settings - Fork 478
view.forceReloaded permanently set to true after frame navigation with data-turbo-action="advance", preventing scroll reset on subsequent Visits #1526
Copy link
Copy link
Open
Description
Environment
- @hotwired/turbo: 8.0.23 (via turbo-rails 2.0.23)
- Browser: Chrome, Safari (all tested)
Description
When a <turbo-frame> with data-turbo-action="advance" navigates and the server responds with a frame-only layout (not a full HTML page), view.forceReloaded is permanently set to true and never reset. This causes performScroll() to skip scrollToTop() on all subsequent Visits for the lifetime of the page.
Steps to reproduce
- Create a
<turbo-frame id="main" data-turbo-action="advance">in your layout - Use a frame-only layout for
Turbo-Frame: mainrequests (standard optimization to reduce response size) - Click a link with
data-turbo-frame="main"to navigate the frame (URL advances) - Now click any link with
data-turbo-frame="_top"that should trigger a full Visit - Expected: page scrolls to top
- Actual: scroll position is preserved (stuck at previous position)
Root cause
In renderPage():
renderPage(e, t = false, s = true, r) {
const i = new RendererClass(this.snapshot, e, t, s);
return i.shouldRender ? r?.changeHistory() : this.forceReloaded = true, this.render(i);
}When the frame response is not a full HTML page, shouldRender returns false, so forceReloaded is set to true.
Then in performScroll():
performScroll() {
this.scrolled || this.view.forceReloaded || this.view.shouldPreserveScrollPosition(this) || (
"restore" == this.action
? this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop()
: this.scrollToAnchor() || this.view.scrollToTop(),
this.scrolled = true
)
}forceReloaded is true, so the entire scroll logic is skipped. Since forceReloaded is never reset to false, every subsequent Visit skips scroll reset.
Expected behavior
forceReloaded should be reset to false before each new Visit, e.g. at the start of Visit.start() or when a new Visit is constructed.
Current workaround
document.addEventListener("turbo:before-visit", () => {
Turbo.navigator.view.forceReloaded = false
})Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels