Skip to content

fix: restore history.state on refresh#12409

Closed
yahao87 wants to merge 1 commit into
sveltejs:version-3from
yahao87:patch-1
Closed

fix: restore history.state on refresh#12409
yahao87 wants to merge 1 commit into
sveltejs:version-3from
yahao87:patch-1

Conversation

@yahao87

@yahao87 yahao87 commented Jun 28, 2024

Copy link
Copy Markdown

fixes? #11956
fixes #9868

Fix the issue with history.state resetting on refresh


Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

Fix the issue with history.state resetting on refresh
@changeset-bot

changeset-bot Bot commented Jun 28, 2024

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 79de427

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@benmccann

Copy link
Copy Markdown
Member

this seems to be an area that's difficult to get right, so I'd really want to have a test for this one

@PatrickG

PatrickG commented Jun 30, 2024

Copy link
Copy Markdown
Member

The maintainers probably haven't discussed this yet, but I think this should be optional as Rich mentioned in the issue.
Also, I don't think this is the correct fix. This would only work if SSR is disabled.

@yahao87

yahao87 commented Jul 1, 2024

Copy link
Copy Markdown
Author

The maintainers probably haven't discussed this yet, but I think this should be optional as Rich mentioned in the issue. Also, I don't think this is the correct fix. This would only work if SSR is disabled.

I don't understand. Why should the framework's default behavior be to block the implementation of basic browser functionality? If a user is building a complex multi-page signup process, they can use history.state to store personal information within the history to preserve it even after a refresh without relying on a store. This history.state can store not only simple objects but also data like files selected through a form. Blocking this forces the use of localstorage.

It's natural that this doesn't work in SSR since it's a browser feature. Isn't it up to the developers using this framework to handle such implementations? The current implementation in Kit2 blocks this, taking away the user's choice.

Our service has been unable to upgrade to Kit2 since last year due to this issue.

@maj0rika

maj0rika commented Jul 1, 2024

Copy link
Copy Markdown

The current behavior of SvelteKit 2, which resets history.state on refresh, poses significant challenges for developers. When building complex multi-page signup processes, using history.state to preserve personal information even after a refresh is extremely useful. This allows developers to store data like files selected through a form without relying on local storage.

Blocking basic browser functionality imposes unnecessary constraints on developers. While it is understandable that history.state would not work in SSR (Server-Side Rendering) environments, limiting its use on the client side is inappropriate.

Moreover, the current implementation in SvelteKit 2 lacks the necessary flexibility. Instead of enforcing specific functionalities, the framework should allow developers to make their own choices. This flexibility is crucial for supporting a wide range of use cases. The inability of certain services to upgrade to SvelteKit 2 due to this restriction highlights the real problems this limitation can cause.

Overall, the current implementation of SvelteKit 2, which restricts the use of history.state, imposes significant constraints on developers and limits support for various use cases. Giving developers the flexibility to choose how they manage state is the right approach. A framework should not block basic functionality but rather empower developers to make decisions based on their specific needs.

@PatrickG

PatrickG commented Jul 1, 2024

Copy link
Copy Markdown
Member

The reason I mentioned SSR is because the solution for the linked issue #11956 (which is about $page.state not history.state) should work with SSR enabled as well.
I guess this PR is supposed to be a fix for #9868 (which IMO should be fixed of course).

@teemingc teemingc changed the title Fix the issue with history.state resetting on refresh fix: restore history.state on refresh Oct 10, 2024
@teemingc teemingc changed the title fix: restore history.state on refresh fix: restore history.state on refresh Oct 10, 2024
@Rich-Harris Rich-Harris added the needs-decision Not sure if we want to do this yet, also design work needed label Aug 20, 2025
@Rich-Harris Rich-Harris added this to the 3.0 milestone Aug 20, 2025
@benmccann
benmccann changed the base branch from main to version-3 February 13, 2026 00:43
@Rich-Harris

Copy link
Copy Markdown
Member

This can't be merged in its current state, per #12409 (comment). At minimum there needs to be an option for it.

But honestly I'm still not totally convinced it's a good idea — I'm not sure page.state is the right tool for the job. For a complex multi-step form it's more reliable to store the incomplete data on the server, so that the user can come back another time (or from another device), but if you do want to keep it in the client then it sounds like snapshots might be a better conceptual fit?

The big caveat is that it's backed by sessionStorage which means there's a limit on what can be serialized there. There's #14129 but it wouldn't help with things like File. I wonder if we could use IndexedDB for snapshots instead. (And also page.state, for that matter. Unfortunately we can't use history.state directly, because you need to be able to capture state after a popstate-driven navigation, and the event fires once the history.state you need to update is already out of reach. But IndexedDB would solve this problem.)

(A smaller caveat is that snapshot has to be used inside +layout.svelte and +page.svelte files, not arbitrary components. If that's a problem, perhaps there's an alternative API we could come up with.)

Notably, the popstate problem will go away when we're eventually in a position to switch to the Navigation API. But we've decided we probably need to keep using history until SvelteKit 4.

@dummdidumm

dummdidumm commented Jul 17, 2026

Copy link
Copy Markdown
Member

Closing in favor of #16389 and #16346 - thank you

@dummdidumm dummdidumm closed this Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-decision Not sure if we want to do this yet, also design work needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Preserve history state on refresh when SSR is disabled

6 participants