Unable to share Svelte store between hydrated components (in dev mode)
See original GitHub issueAccording to the docs, hydrated components should be able to share a store:
With partial hydration you end up with multiple root components instead of one main component root. (Don’t worry, you can still use Svelte stores to allow them to easily share state across them.) ― https://elderguide.com/tech/elderjs/#understanding-partial-hydration
However I’m unable to get this to work. The hydrated component bundles appear to each have their own copy of the store. Do you have a working example you can share? Maybe even add it to the Elderjs/template?
This is a simplified version of my unsuccessful setup (inspired by the Svelte tutorial: writable stores):
src/routes/app/App.svelte
:
<script>
import '../../components/CountDisplay.svelte';
import '../../components/CountIncrementer.svelte';
</script>
<CountDisplay hydrate-client={{ }} />
<CountIncrementer hydrate-client={{ }} />
src/store.mjs
:
import { writable } from 'svelte/store';
export const count = writable(0);
CountDisplay
:
<script>
import { count } from './stores.js';
let count_value;
count.subscribe(value => {
count_value = value;
});
</script>
<h1>The count is {count_value}</h1>
src/components/CountIncrementer.svelte
:
<script>
import { count } from './stores.js';
function increment() {
count.update(n => n + 1);
}
</script>
<button on:click={increment}> + </button>
I didn’t get this to work. So instead I ended up sharing a store by exposing it to the window object onMount:
src/components/CountStore.svelte
:
<script>
import { writable } from 'svelte/store';
const count = writable(0);
onMount(() => {
window.count = count;
});
</script>
This way other hydrated components have access via window.count.subscribe
/window.count.update
/etc.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
For anyone looking for this, it looks like you can set legacy mode in the elder.config.js to allow svelte stores to work in dev. You can set this to just run in legacy mode during development, since stores work in production already. module.exports = { … legacy: process.env.NODE_ENV === ‘development’ ? true : false, … }
You can also edit the dev server port by setting an env variable in the command like
Yup, this was the issue.
Stores are only working with production builds where they are rolled up together. 😕
Example: https://imgur.com/a/va6aA4A
(Had to change a few of the file paths but got it working no prob)
This is a trade off of slower bundling during dev.
We could add a flag in the Elder.js config to always bundle together in watch mode and have it skip terser/babel.