DEV Community

Mutating Query Params in SvelteKit Without Page Reloads or Navigations

Mohamad Harith on December 24, 2021

This article assumes the reader understands the basics of SvelteKit framework. SvelteKit is a rather new framework for building server-side render...
Collapse
 
raz0229 profile image
RAZ0229

This is it. Can't believe i spend hours finding other solutions

Collapse
 
codinghusi profile image
Gerrit Weiermann

Thanks for sharing!
I have two improvements:

  1. url.searchParams.set does encodeURLComponent internally so you can remove it
  2. I figured out that you need to pass history.state to the replaceState function. Otherwise routing will break:
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(k, v);
    } else {
      url.searchParams.delete(k);
    }
  }
  history.replaceState(history.state, '', url);
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
pptavozl profile image
Gustavo Zimbrón

Useful! Thank you!

Collapse
 
frederikhors profile image
frederikhors

Thanks a lot. What about Svelte 5? I'm getting this warning using this code:

Avoid using `history.pushState(...)` and `history.replaceState(...)` as these will conflict with SvelteKit's router. Use the `pushState` and `replaceState` imports from `$app/navigation` instead.
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dangelomedinag profile image
dangelo

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.

Collapse
 
spudunk profile image
Christopher Hicks

In my case I only have one set of params so I just ditched the function and used this:

$page.url.searchParams.set(k, v);
history.replaceState(history.state, '', $page.url);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
askrodney profile image
Rodney Lab

Neat, and welcome to dev.to! Any exciting SvelteKit project you're working on right now?

Collapse
 
spudunk profile image
Christopher Hicks

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?

Thread Thread
 
askrodney profile image
Rodney Lab

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!

Thread Thread
 
spudunk profile image
Christopher Hicks

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!

Collapse
 
chrisjayden profile image
MultipleHats

Maybe it's me, but I think you forgot the add undefined to the Record value as well.

export const replaceStateWithQuery = (values: Record<string, string | undefined>) => {
     ....
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
leon8ix profile image
8ix – peace in unity

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.

Collapse
 
fromaline profile image
Nick

Thanks a lot! I spent a couple hours finding the right solution. Yours is great!