Skip to content

Svelte 5: Preserve local state during HMR #14434

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bhuynhdev opened this issue Nov 25, 2024 · 7 comments
Open

Svelte 5: Preserve local state during HMR #14434

bhuynhdev opened this issue Nov 25, 2024 · 7 comments

Comments

@bhuynhdev
Copy link

bhuynhdev commented Nov 25, 2024

Describe the bug

With a brand new SvelteKit project with Svelte 5, I realized that all my states are reset whenever HMR updates

Whenever I change anything in the HTML part of a Svelte file, HMR kicks in and resets all my $state, which makes it very cumbersome to develop a large and complex form

I read that earlier version support directives such as @hmr:keep-all or preserveLocalState, but according to sveltejs/kit#12985, these are outdated and no longer used

So I am unsure what to do now to preserve states between HMR reloads - is this a bug or a feature request?

Reproduction

Reproduction link in SvelteLab: https://www.sveltelab.dev/63iv5zkf3ed2806

Steps to reproduce:

  1. Check the checkbox
  2. Click the button
  3. Change something in the HTML, like adding more text to the paragraph
  4. All states get reset - the checkbox gets unchecked, and text resets to initial value 🚩

I understand that SvelteLab may not reflect real-world environments, but I tried it on my laptop inside WSL and the "bug" is still there

Logs

No response

System Info

System:
    OS: Linux 5.15 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
    CPU: (8) x64 AMD Ryzen 7 8845HS w/ Radeon 780M Graphics
    Memory: 13.97 GB / 14.90 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 23.3.0 - ~/.local/share/mise/installs/node/23/bin/node
    npm: 10.9.0 - ~/.local/share/mise/installs/node/23/bin/npm
    pnpm: 9.14.2 - ~/.local/share/mise/installs/node/23/bin/pnpm
  npmPackages:
    svelte: ^5.1.13 => 5.1.13

Severity

annoyance

@apekros
Copy link

apekros commented Dec 5, 2024

Also just ran into this issue with tauri+Svelte 5, would love to have something like the directives or preserveLocalState support

@dominikg
Copy link
Member

dominikg commented Dec 5, 2024

you can add this code to the end of your script block to manually preserve the checked state

	if (import.meta.hot) {
		if (import.meta.hot.data.checked != null) {
			checked = import.meta.hot.data.checked;
		}
		import.meta.hot.accept();
		import.meta.hot.dispose(() => {
			import.meta.hot.data.checked = checked;
		});
  }

It may be possible to extend the svelte compiler to parse annotations and create this code for you, however it should always be used as a scalpel.

@ngoov
Copy link

ngoov commented Mar 19, 2025

Are there any plans to add this to the kit configuration? It's a shame that by replacing svelte-hmr and vite's default HMR, SvelteKit does not support this functionality anymore. It's kind of a step backwards IMO.

And adding code at the end of a script block to keep track of all the client state is not feasible...

@Saltallica
Copy link

I agree - HMR not preserving state loses much of its usefulness. It is intended to be a productivity tool.

if I can't adjust my HTML and see the output applied to the existing state, it's no better than just reloading a page and starting over.

There is no way in hell I am bolting in a bunch of stuff for every component for what should be provided out of the box.

@dominikg
Copy link
Member

dominikg commented Apr 10, 2025

It's a shame that by replacing svelte-hmr and vite's default HMR, SvelteKit does not support this functionality anymore. It's kind of a step backwards IMO

this was never a default feature of vite hmr, the code I posted above is what you have to do to preserve local state in vite hmr.
svelte-hmr had a custom implementation to automate some of this for you, but it comes with the caveats described in
svelte-hmr readme and was disabled by default.

If state reset is getting in the way of your dx, in some cases it can be a sign that the state shouldn't be local to that component but instead held in a different module. If you refactor it and pass it in via prop, the value will be preserved when the component updates.

@darkstarx
Copy link

Compared to Flutter, it's terrible. The state of the component should not be reset while editing its html code out of the box.

@ngoov
Copy link

ngoov commented May 5, 2025

It's a shame that by replacing svelte-hmr and vite's default HMR, SvelteKit does not support this functionality anymore. It's kind of a step backwards IMO

this was never a default feature of vite hmr, the code I posted above is what you have to do to preserve local state in vite hmr. svelte-hmr had a custom implementation to automate some of this for you, but it comes with the caveats described in svelte-hmr readme and was disabled by default.

If state reset is getting in the way of your dx, in some cases it can be a sign that the state shouldn't be local to that component but instead held in a different module. If you refactor it and pass it in via prop, the value will be preserved when the component updates.

I guess I was comparing it to React's Fast Refresh then, my bad. It does this OOTB for every component change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants