kit
kit copied to clipboard
Add Link Option `data-sveltekit-invalidate`
Describe the problem
My client noted that when clicking the same link (user is already on) they expect the page data to reload. I must agree that in certain cases it makes sense. SvelteKit currently does nothing when user is clicking the same link over and over.
Describe the proposed solution
I propose to add data-sveltekit-invalidate link option. When user is navigating on some other page nothign will change from current system. Howerver when user clicks on the same link again and the data-sveltekit-invalidate option is present SvelteKit triggers the page load() function again and SvelteKit treats this action as if user is navigating to another page.
Alternatives considered
I have tried adding on:click event to links:
function handleClick() {
if (this.href === $page.url.href) {
invalidate('page:data')
}
}
This almost works, however the load function runs twice. I asume that one runs for the invalidate event and the other runs for the navigation event.
Another try:
function handleClick() {
if (this.href === $page.url.href) {
goto(this.href, {
replaceState: true,
invalidateAll: true,
})
}
}
This almost works too however invalidating all the resources is not the desired outcome.
Importance
would make my life easier
Additional Information
No response
I don't think a link option will suffice here - what exactly should be invalidated? If it's not everything but specific things - like in your case - it makes more sense to solve this programmatically.
Possibly we need an invalidate option for goto which would allow you to refresh things more granularly.
Another possibility is that you add a click handler to the a tag and do preventDefault/stopPropagation on it if the url is the same and do invalidate instead; shouldn't rerun twice then.
I agree that this could be done with combination of goto and invalidate functionality. I don't like the syntax for this solution too much. Applying custom click event and overwriting kit's core functionality is't very pretty, in my opinion. Perhaps a tag data-sveltekit-invalidate would re-trigger only page load function but data-sveltekit-invalidate-all or data-sveltekit-invalidate="all" would trigger all the load functions. Or perhaps data-sveltekit-invalidate="/something:something" would run equivalent of running invalidate('/something:something'). With one exception, this event would seem as if user is navigating and the $navigating store would be triggered as well.
It's something to think about. I am personally fine with only limited functionality. No need to overthink it. Limited functionality might be better than none at all.
Here's my workaround. In the root layout:
let navigationToggle = false
onNavigate(navigation => {
if (navigation.to?.url.toString() === navigation.from?.url.toString()) {
navigationToggle = !navigationToggle
}
})
And then I wrap the part of the layout I want to reload in {#key navigationToggle}{/key}. You probably just want to re-render the page, not the layout, so you'd typically do this:
{#key navigationToggle}
<slot />
{/key}