inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.56k stars 435 forks source link

[1.x] Fix history navigation issue on Chrome iOS #1984

Closed pedroborges closed 2 months ago

pedroborges commented 2 months ago

On Chrome iOS, calling this.storeScrollPositions (which uses history.replaceState) right before this.setPage in the router visit method caused timing issues with history.pushState, leading to navigation problems.

Wrapping window.history.pushState with setTimeout inside router.pushState fixes the issue. Using setTimeout defers history.pushState to the next event loop tick, preventing conflicts between history.replaceState and history.pushState. This change doesn’t introduce any side effects since setTimeout with a delay of 0 just delays the execution without altering functionality.

Fixes #1954.

Before

https://github.com/user-attachments/assets/f7ad94e9-46fb-4bec-9897-8d54758cd951

After

https://github.com/user-attachments/assets/2bb29406-ceb8-41ef-b4bd-8a5bff2f75f0

We could enhance this by detecting Chrome on iOS and only applying setTimeout there, but the current fix works universally without issues 🤷‍♂️

AbdullahAgsar commented 2 months ago

This solution didn’t work. I cloned it from the master branch and used these changes in my project with npm link. While the issue persists on iOS browsers, I also started experiencing problems on browsers on my macOS device. @pedroborges

pedroborges commented 2 months ago

@AbdullahAgsar Yeah, I noticed last week that this fix caused some side effects on macOS browsers as well. Could you try the fix from #1992? I just tested it again and it resolves the navigation issues for me.

AbdullahAgsar commented 2 months ago

@pedroborges I tried the solution from #1992, but it didn’t work. I continue to experience issues with both forward and backward navigation in macOS browsers. Additionally, the issue in iOS browsers still persists.

pedroborges commented 2 months ago

@AbdullahAgsar Thanks for the feedback. Just to confirm, are you testing this in your project or one of the playgrounds?

Also, would you be able to provide a minimal reproducible repository? I’d love to investigate the issue further.

AbdullahAgsar commented 2 months ago

@pedroborges I tested it in my own project. I will try to create a blank project where the same issue occurs, and once completed, I will share the GitHub link with you.

pedroborges commented 2 months ago

@AbdullahAgsar Thanks, I’d really appreciate your help in reproducing the issue. I just tested #1992 on the Vue and Svelte versions of Ping CRM, and it resolved the navigation issue in those projects as well.

AbdullahAgsar commented 1 month ago

Hello @pedroborges, I’ve been trying to solve the issue I’ve been facing for a long time using your solution. The issue wasn’t only present in iOS Chrome but also in iOS Edge. After making some adjustments along with your solution, I was able to come up with a fix for both browsers.

Initially, in the resolve block, I was using the following code:

const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]

But I had modified it to:

const pages = import.meta.glob('../../Pages/**/*.vue')
return pages[`../../Pages/${name}.vue`]()

After reverting this code back to its original state, most of the issues were resolved. However, I was still experiencing problems with the back navigation, like adding the same page to the history twice. To resolve these, I removed the Chrome check from the replaceState() function and adjusted it like this: window.history.replaceState(cloneSerializable(page), '', page.url)

For the Edge browser, I created a variable called isEdgeIOS. With these changes, I was able to fix all the back navigation issues on both browsers.

Screenshot 2024-10-08 at 13 51 54

Screenshot 2024-10-08 at 13 52 20