hotwired / turbo

The speed of a single-page web application without having to write any JavaScript
https://turbo.hotwired.dev
MIT License
6.73k stars 428 forks source link

Back button doesn't work when next and previous restorationIndetifiers from turbo history the same #1333

Open volodymyr-nt opened 3 days ago

volodymyr-nt commented 3 days ago

Hi. I have filter form where i fetch turbo stream responses and push state updates with

Turbo.navigator.history.push(filterUrl)

Following flow is broken:

  1. / page loaded.
  2. I apply filter(which does Turbo.navigator.history.push(filterUrl)) - updates url, pushes state - everything ok.
  3. I click back button - it updates url but it doesn't perform navigation.

I found only one workaround for this using stimulus:


// Stimulus filter component
connect() {
  window.addEventListener("popstate", this.handlePopstate);
}
handlePopstate = (e) => {
  if (!Turbo.navigator.formSubmission && !Turbo.navigator.adapter.progressBar?.visible) {
    Turbo.visit(window.location.href, { action: "advance" })
  }
}

Is this bug in stimulus? Are there some options or more elegant workarounds?

volodymyr-nt commented 3 days ago

Upd: Found that problem lies in this line: https://github.com/hotwired/turbo/blob/ea54ae5ad4b6b28cb62ccd62951352641ed08293/src/core/drive/navigator.js#L138 In my case i navigate back to / page which is the same page that was rendered by Turbo last time

Alternative workaround is about doing push and setting lastRenderedLocation:

<%#  In <head> for filter page or globally %>
<meta name="turbo-cache-control" content="no-cache">
Turbo.navigator.history.push(filterUrl);
Turbo.navigator.view.lastRenderedLocation = filterUrl;
// or
Turbo.navigator.history.push(filterUrl);
Turbo.session.pageBecameInteractive(); 

Would be nice to have the same behavior like listed in code snippet above as one method and part of public Turbo api.