Skip to content
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

page.params from $app/state is not reactive where as from $app/stores is reactive #13305

Closed
mkmoisen opened this issue Jan 13, 2025 · 5 comments

Comments

@mkmoisen
Copy link

Describe the bug

I apologize if this is something simple, I have read the documentation on $app/state/page and believe that this should work the same as it does for $app/stores/state but it does not.

It seems that $app/state/page lacks the reactivity that $app/stores/page has.

/foos
    [fooId]
        +page.svelte
<script>
    import { page } from '$app/state';
    
    $: fooId = page.params.fooId;
</script>

<h1>{fooId}</h1>

<a href="/foos/1">1</a>
<a href="/foos/2">2</a>

Clicking on the link here will no longer cause the page.params.fooId to change. The URL is correctly updated when clicking on the link, but $fooId = page.params.fooId does not react.

This works works fine when using { page } from '$app/stores':

    import { page } from '$app/stores';
    $: fooId = $page.params.fooId;

Reproduction

/foos
    [fooId]
        +page.svelte
<script>
    import { page } from '$app/state';
    
    $: fooId = page.params.fooId;
</script>

    <h1>{fooId}</h1>

    <a href="/foos/1">1</a>
    <a href="/foos/2">2</a>

Logs

No response

System Info

npmPackages:
    @sveltejs/adapter-static: ^3.0.6 => 3.0.8
    @sveltejs/kit: ^2.0.0 => 2.15.2
    @sveltejs/vite-plugin-svelte: ^4.0.0 => 4.0.4
    svelte: ^5.0.0 => 5.16.6
    vite: ^5.4.11 => 5.4.11

Severity

blocking an upgrade

Additional Information

No response

@mkmoisen
Copy link
Author

This does work when using svelte5 $derived runes:

<script>
    import { page } from '$app/state';
    
    let fooId = $derived(page.params.fooId);
</script>

<h1>{fooId}</h1>

<a href="/foos/1">1</a>
<a href="/foos/2">2</a>

And this works too:

<script>
    import { page } from '$app/stores';
    
    let fooId = $derived($page.params.fooId);
</script>

<h1>{fooId}</h1>

<a href="/foos/1">1</a>
<a href="/foos/2">2</a>

But why won't it work using $ reactivity with /app/stores/page?

@brunnerh
Copy link
Member

brunnerh commented Jan 13, 2025

$app/state uses rune-based reactivity while $: uses legacy compile-time-based reactivity.
They do not work together because the $app/state is more fine-grained, the generated output would only observe the top level object, i.e. page which itself does not change.

$.legacy_pre_effect(() => (page), () => {
	$.set(fooId, page.params.fooId);
});

(If you force runes mode via <svelte:options runes /> you will also get an error because $: is not supported in the new system.)

$app/state is meant to be used with runes, so you should use $derived here.

@mkmoisen
Copy link
Author

@brunnerh

That makes sense, thank you.

Would it be worthwhile to update the sveltekit $app/state/page documentation to give some examples of how it should be used differently compared to $app/stores/page?

https://svelte.dev/docs/kit/$app-state#page

Another question, I see that that $app/stores/page is deprecated. This would have the effect of encouraging us to move to Svelte5 style runes.

Is svelte planning on getting rid of the legacy $ reactivity? If so then the deprecation of $app/stores/page makes sense. But if not, then perhaps $app/stores/page should not be deprecated?

@brunnerh
Copy link
Member

Would it be worthwhile to update the sveltekit $app/state/page documentation to give some examples of how it should be used differently compared to $app/stores/page?

Possibly.

Is svelte planning on getting rid of the legacy $ reactivity?

Yes, it will eventually be removed in some later major version of Svelte.

@jdhuntington
Copy link
Contributor

Would it be worthwhile to update the sveltekit $app/state/page documentation to give some examples of how it should be used differently compared to $app/stores/page?

Would heartily endorse it if at all possible! I'm new to svelte and updating a page based on URL params is the first interesting thing I've tried to do. I've spent many hours trying to figure out why the most basic thing isn't working. I suspect this is a thing on the critical path for beginners and some docs here would have high ROI.

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

No branches or pull requests

3 participants