-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the problem
While trying to make use of goto and invalidateAll, I couldn't get my page to call its load function predictably. It turns out, my page's load method had no dependencies that would trigger it to change, even though it's a navigational change with different params.
Details for those curious
My example project
The layout and page files are in this file structure:
src/routes/[branch]/+layout.sveltesrc/routes/[branch]/+layout.server.jssrc/routes/[branch]/thing/[id]/+page.sveltesrc/routes/[branch]/thing/[id]/+page.server.js
The broken behaviour:
- Given the current page is
/main/thing/abc123 - When the user clicks a button in a 'Switch branch' dropdown (kinda like GitHub branches)
- Then it calls
goto('/otherbranch/thing/abc123') - And the target
[branch]param has changed, and[id]stayed the same. - But the target
+page.server.js'sloadmethod was not called again
In +page.server.js, I have:
/** @type {import('./$types').PageServerLoad} */
export async function load ({ params, locals }) {
if (!params.id) {
// No id
throw error(400, 'No ID provided')
}
// get db connection passed in from `src/hooks.server.js@handle`
// which actually makes use of `params.branch` but isn't explicitly utilized in this `load`
const { db } = locals
// ... do db stuff
return { rows }
}It calls params.id, but it does not call params.branch, so I assume SvelteKit is aggressively optimizing this load to not invalidate if params.branch ever changes; and I was unaware. I made this adjustment, and now load runs after I call goto('/different-branch-from-before/thing/abc123'):
+ export async function load ({ params, locals, depends }) {
+ depends(params.branch) // this is probably wrong and I'm sorryI came across this insightful comment: #1684 (comment)
It describes how goto calls a page (or layout's) respective load under the following conditions:
goto()will only runload()ifpage.params,page.path,page.query,sessionorcontextis used inside ofloadand one of those values has changed since the last run of the load function.
On the surface this makes sense, the load method needs to have some sort of changed params in order for goto to call it again. However, I could not find this behaviour in the docs, and I still have uncertainties:
- Does
page.paramsrefer to the$pagestore used on thatloadmethod's respective+page.svelte? Or does it (more likely) refer toevent.paramsused inload? - How do I tell my page and its parent layout to call
loadwhengotonavigates to that page? - Is there a way to tell a
loadto always refetch values if the user navigates to it? I understand it's optimal to make use ofdepends, but I don't understand its functionality, either. - How do I make use of
dependsso that if a path param changes, thatloadshould invalidate? I assume it'sdepends(params.targetParam), but I don't know.
Describe the proposed solution
I'm happy to work with the team to add some details to the docs to better capture the behaviour of goto and when it would or would not call load on the target route, how to assign path params to depends within load, and any applicable side-effects of these features.
Alternatives considered
I guess I could do without the event.locals trickery and be more explicit with my dependencies in load, but I wanted to avoid some boilerplate.
Importance
would make my life easier
Additional Information
This comment was also very informative and parts of it should probably make it to the docs: #2560 (comment)
Specifically the detail on how hard copies of store values will get properly recognized as changed in SvelteKit's optimization logic.