sveltejs / kit

web development, streamlined
https://svelte.dev/docs/kit
MIT License
18.64k stars 1.92k forks source link

pushState and replaceState causing inconsistencies with different url #11465

Open AlexisGado opened 10 months ago

AlexisGado commented 10 months ago

Describe the bug

When calling pushState or replaceState with a first argument that is not the current page's url, subsequent navigations (typically "go back") will lead to unexpected behaviors. In particular, the url in the browser's history will be different from the one used in the load function of a page.

See for example this SO question which explains the bug that led me here: https://stackoverflow.com/questions/77703203/url-is-incorrect-in-load-after-pushstate-and-navigation

I'm not a svelteKit contributor, and am not ready yet to be one, but I think the bug is caused by these lines: https://github.com/sveltejs/kit/blob/acec5e6a2c6325ee226594664e8ba723d1b81e17/packages/kit/src/runtime/client/client.js#L1617 https://github.com/sveltejs/kit/blob/acec5e6a2c6325ee226594664e8ba723d1b81e17/packages/kit/src/runtime/client/client.js#L1642

PAGE_URL_KEY is set to the current page's url while the original history API is called with the new url provided by the user. Changing page.url.href to resolve_url(url).href solved my issue.

Reproduction

https://github.com/AlexisGado/bug-nav-svelte

Logs

No response

System Info

System:
    OS: macOS 14.0
    CPU: (8) arm64 Apple M1
    Memory: 59.53 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.4.0 - /opt/homebrew/bin/node
    npm: 10.2.4 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 119.0.6045.123
    Safari: 17.0

Severity

serious, but I can work around it

Additional Information

If you know a better way of doing what I was trying to achieve, please feel free to answer the SO question :)

eltigerchino commented 2 weeks ago

This has the same issue as https://github.com/sveltejs/kit/issues/11503 where we are trying to avoid updating the page store with the URL passed to pushState and instead keep the page store URL and load URL the same as the original page we were on. However, we should be updating the load URL.