This article assumes the reader understands the basics of SvelteKit framework.
SvelteKit is a rather new framework for building server-side rendered websites. Because it is new, some of the early adopters of the framework were confused on certain usages of the framework. One such confusion was on the usage of query params as seen in these issues: #2785, #969, #2811 - many people, including myself were confused on how to mutate query params of a page without page reloads or navigations.
Some of us thought mutating the params property of $page store would mutate the query params. But this wasn't the cause because the $page store was a read-only store.
Since SvelteKit does not provide a way to mutate the query params, my HOD and I figured that we use the History API's replace state to mutate the query params.
The function:
export const replaceStateWithQuery = (values: Record<string, string>) => {
const url = new URL(window.location.toString());
for (let [k, v] of Object.entries(values)) {
if (!!v) {
url.searchParams.set(encodeURIComponent(k), encodeURIComponent(v));
} else {
url.searchParams.delete(k);
}
}
history.replaceState({}, '', url);
};
The usage:
onMount(() => {
// adds ?foo=bar&john=doe query params to the URL
replaceStateWithQuery({
foo: 'bar',
john: 'doe',
});
});
The replaceStateWithQuery is a function that receives an object of query params and uses the History API's to set these values as the query params of the page. Both the keys and values of the query params will be URL encoded by default. If the value of a query param is null
or undefined
, the query will be deleted from the URL.
Top comments (13)
This is it. Can't believe i spend hours finding other solutions
Thanks for sharing!
I have two improvements:
url.searchParams.set
doesencodeURLComponent
internally so you can remove itUseful! Thank you!
Thanks a lot. What about Svelte 5? I'm getting this warning using this code:
this is amazing. when you travel to the same page through a link, the client side router removes the replaced query parameters from 'onMount' and it is understandable, since the component is not mounted again. So keep that in mind.
thanks for the post.
In my case I only have one set of params so I just ditched the function and used this:
Neat, and welcome to dev.to! Any exciting SvelteKit project you're working on right now?
Thanks! And yeah, this problem was applied to Eagans Diner Website for the Ethel location menu tab query
Also been learning a lot on Walking CJ Ranch Website. Some fun image optimization in there using Unpic and Cloudinary.
code for both is in my repo spudunk
What are you working on?
Nice, had a scan through your GitHub, hope you're getting paid what you deserve for all this work!
Been looking at using SvelteKit with Tauri to create desktop apps myself, combining Svelte with Rust. Enjoying the experience so far!
Svelte + Rust seems like a powerful combo! If I get into desktop app territory I'll try that route.
Getting paid what it's worth is still a goal!
Maybe it's me, but I think you forgot the add
undefined
to the Record value as well.I already had your solution implemented. But this totally breaks all back navigation. So i was searching for a better way and I just found a fix.
Instead of doing:
history.replaceState({}, '', url);
You need to write:
history.replaceState(history.state, '', url);
This keeps SvelteKit's router intact and back navigation still works.
Thanks a lot! I spent a couple hours finding the right solution. Yours is great!