I have a page with a search field. If accessed with a query parameter (e.g. ?word=cat
) the page should load with results present and the search field filled. If a search is done the results and the query parameters (browser history) should update.
The only way I found to update query parameters is goto
, so my attempt is:
<script context="module">
export async function load({ page, fetch }) {
const response = await fetch(`/data.json?${page.query.toString()}`)
if (response.ok) {
return {
props: {
word: page.query.get('word'),
body: await response.json()
}
}
}
}
</script>
<script>
import { goto } from '$app/navigation'
import { page } from '$app/stores'
export let word
export let body
function search() {
$page.query.set('word', word)
goto(`?${$page.query.toString()}`)
}
</script>
<main>
<form on:submit|preventDefault={search}>
<input bind:value={word}>
</form>
<!-- ... -->
</main>
This works but sometimes gets stuck just updating the query parameters and nothing else. For some reason load
isn't being called in those cases. I can get it to work reliably by adding await invalidate
for the URL before the goto
, but now load
is always called twice and the search field flips back to the old value shortly.
I just started with Svelte/SvelteKit, so my approach is probably just wrong. Thanks for any help.
I had similar issue triggering load
function and I solved it by creating new instance of the URLSearchParams
and navigating to these new params.
let query = new URLSearchParams($page.url.searchParams.toString());
query.set('word', word);
goto(`?${query.toString()}`);