kit: invalidate: callback not called for server load, invalidate never reloads server endpoints
Describe the bug
I’m not really sure if this is intentional or a bug, but anyway:
invalidateAll
correctly triggers all load functions including calling the server side equivalents (+layout.server.ts, +page.server.ts).
Accordingly, I would expect the callback passed to invalidate
to be called with some URL that represents the server side load functions to selectively trigger a refetch of those resources. However, it is only called for URLs used in explicit fetch or depends calls in load functions. As a consequence, invalidate( () => true)
does not behave like invalidateAll
. I realize it’s not documented to behave the same, but intuitively I’d expect it to.
As a corollary, there is no URL that can be passed to invalidate (the non-callback version) that would reload the server side endpoints. The only way to trigger server side page/layout endpoints to reload is by using invalidateAll.
Reproduction
See https://stackblitz.com/edit/sveltejs-kit-template-default-zrzasd?terminal=dev
The page shows the timestamp of the data coming from different layers (server side layout load, layout load, server side page load, page load).
The button “Test invalidate” invokes invalidate and collects all URLs passed to the callback (note that the callback always returns false - we do not actually need to refresh anything for this test). The page shows the list of URLs that were passed to invalidate.
Note that the explicit dependencies “app://layout-load” and “app://page-load” show up in the list, but nothing more.
“Test invalidate with refresh” does the same but returns true from the callback. This causes the two load functions to run, but does NOT invoke the server side endpoints to be called. As a result, the server side data is missing from $page.data.
“Invalidate all” calls invalidateAll which refreshes all data as expected.
Logs
No response
System Info
(Stackblitz)
System:
OS: Linux 5.0 undefined
CPU: (4) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 16.14.2 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 7.17.0 - /usr/local/bin/npm
npmPackages:
@sveltejs/adapter-auto: next => 1.0.0-next.73
@sveltejs/kit: next => 1.0.0-next.481
svelte: ^3.46.0 => 3.50.1
vite: ^3.1.0 => 3.1.0
Severity
serious, but I can work around it
Additional Information
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 15 (11 by maintainers)
Filed the bug as #6929
The stackblitz in my original post does not reflect what I said in my later posts.
Here’s an example that shows different scenarios for invalidate: https://stackblitz.com/edit/sveltekit-selective-invalidation?file=src%2Froutes%2F%2Bpage.svelte
(Note that I wrote earlier that triggering a server side load would not trigger the shared/isomorphic load if both are present, but that’s not true. The shared load - if present - is always called when the server side load is called - which makes sense, because the server side data always has to pass through the shared load function and is not automatically merged into PageData.)
BTW: yes “isomorphic load” refers to +page.ts or +layout.ts whereas “server load” refers to +page.server.ts and +layout.server.ts.
BUT: I just realized that the typescript types are not complete -
depends
is not defined inServerLoadEvent
but is actually passed in (and works, see the stackblitz). I’ll file an issue.This is intended behaviour. If you need to invalidate a specific
load
function (server or shared) you can usedepends
with a custom identifier. This is already documented in thedepends
andinvalidate
docs, I’m not sure that there’s more we can do?