Why Don't My SvelteKit Invalidations Work?
You think you're using SvelteKit as prescribed, and following the instructions in the invalidations docs, but your invalidations don't seem to be working. In fact, you can open the browser developer tools and see the network request being made to get the updated data, but the page doesn't update. What gives?!
Bottom line up front: You're probably not referencing a reactive variable.
A quick refresher on reactive variables
<script lang="ts">
let count = $state(0);
</script>
<button onclick={() => count++}>{count}</button>
When you click the button, the count goes up, and you can see it update on the button label. This works because of the magic of the $state()
rune. Svelte is made aware that the value is expected to change over time and when it does, things that reference it should be re-rendered.
But if you change let count = $state(0);
to simply let count = 0;
then your button label does not update.
How reactive variables apply in this case
If you're like me, your page probably looks something like this:
<script lang="ts">
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
let { foo, bar, baz } = data;
</script>
{#each foo as item}
<div>{item}</div>
{/each}
In this case, the data
variable pulled from $props()
is reactive. But when you destructure it, it is no longer reactive. You have a couple of options.
- Reference everything from
data
directly, like this:
<script lang="ts">
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
</script>
{#each data.foo as item}
<div>{item}</div>
{/each}
- Use the
$derived()
rune to create a reactive variable that references the destructured values:
<script lang="ts">
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
let foo = $derived(data.foo);
</script>
{#each foo as item}
<div>{item}</div>
{/each}
Either way, as long as you're referencing reactive variables, they should update as expected when invalidate()
runs.