Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
Back to tool/Back to issues
#1526·turbo

view.forceReloaded permanently set to true after frame navigation with data-turbo-action="advance", preventing scroll reset on subsequent Visits

Author: Xeross99Created Mar 26, 2026Updated Jun 23, 2026

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

  1. Create a <turbo-frame id="main" data-turbo-action="advance"> in your layout
  2. Use a frame-only layout for Turbo-Frame: main requests (standard optimization to reduce response size)
  3. Click a link with data-turbo-frame="main" to navigate the frame (URL advances)
  4. Now click any link with data-turbo-frame="_top" that should trigger a full Visit
  5. Expected: page scrolls to top
  6. Actual: scroll position is preserved (stuck at previous position)

Root cause

In renderPage():

javascript
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():

javascript
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

javascript
document.addEventListener("turbo:before-visit", () => {
  Turbo.navigator.view.forceReloaded = false
})

Source: hotwired/turbo

View original on GitHubView discussion on GitHub