Fix turbo:load firing twice after a redirect and avoid double render#563
Fix turbo:load firing twice after a redirect and avoid double render#563dhh merged 7 commits intohotwired:mainfrom
turbo:load firing twice after a redirect and avoid double render#563Conversation
|
Looks like we have some test failures? |
* main: Fix lint violations
|
Want to take a look at this @feliperaul? |
|
@dhh Hi David, thanks for bumping me on this. I wish I could help further... the fact is that when I issued the PR I added a test for my change, and the test is passing on Firefox, but after literally hours of attempts I couldn't make it pass on Chrome (it always fails with this Sorry for issuing a PR with a failing test, but I mentioned this on the comment above hoping someone could chip in and get this test passing on Chrome so this could be merged. I hit a wall here. Maybe you could cc someone that could give it a try? |
|
I wonder if visits should handle redirects internally, or have some way of determining a visit that originated from a redirect e.g. via a property on the |
* main: Allow frames to scroll smoothly into view (hotwired#607) Export Type declarations for `turbo:` events (hotwired#452) Add .php as a valid isHTML extension (hotwired#629) Add original click event to 'turbo:click' details (hotwired#611) Drive Browser tests with `playwright` (hotwired#609) Allow Turbo Streams w/ GET via `data-turbo-stream` (hotwired#612) Only update history when Turbo visit is renderable (hotwired#601) Support development ChromeDriver version overrides (hotwired#606) Turbo stream source (hotwired#415) Expose Frame load state via `[complete]` attribute (hotwired#487) fix(ie/edge): form.method='delete', raises Invalid argument. (hotwired#586) Do not declare global types/constants (hotwired#524) Defensively create custom turbo elements (hotwired#483) Use `replaceChildren` in StreamActions.update (hotwired#534)

Hi there! This is my first contribution to turbo.
This fixes #428, #526 and may fix #537 as well.
Turbo is firing
turbo:loadtwice when the server responds with a redirect (regardless of status code, it happens with 302, 303).This is harmful because per the official docs,
turbo:loadreplaces the nativeDOMContentLoaded, which never fires twice on a redirect. The docs clearly stateturbo:loadshould fire only once.Our team had to halt the migration to Turbo because of this; not only analytics events listening to
turbo:loadwere registering two visits while there actually just one, but many pages hadGETand evenPOSTjavascript events fired onturbo:load, some of them that even updated a Rails model'slock_versionon the backend, making it so that when the second render was actually mounted on the screen it couldn't save the model because it was already stale (due to the previous "ghost" turbo:load inadvertently firing).Our code is idempotent; the fact is Turbo is firing
turbo:loadtwice and it's impossible to distinguish one from another (let alone this shouldn't be a extra burden on the developer).I'm aware of the pull request at #516 , but it appears to only solve the double render, but the event will still fire twice;
I tested it and it does not solve the double
turbo:loadfiring. This pull request solves both issues.PS: I added a test that is passing on Firefox, but after hours of attempts I couldn't make it pass on Chrome (it fails with a
StaleElementReference, and I couldn't find any test on the suite that asserted events after a redirect).You will also see
NavigationTests - skip link with hash-only path moves focus and changes tab orderfailing, but it is already failing onmainso it didn't break due to this pull request.