I need all the below code to be able to persist in the URL (query string) some variables I’m using in a Svelte 5 / Svelte Kit project page.
I also need to assign URL query params to variables on page reload or page change.
As you can see the code is very repetitive and I think there must be a better way! (better = DRY and faster)
I created a small reproduction.
What do you think?
// condition, pagination and searchText comes from $props()
let firstLoad = $state(true);
$effect(() => {
if (firstLoad) return;
const url = new URL(window.location.toString());
const paramCondition = url.searchParams.get('condition');
const paramPagination = url.searchParams.get('pagination');
const paramSearchText = url.searchParams.get('searchText');
const actualCondition = isAnEmptyOrFalsyObject(condition) ? null : JSON.stringify(condition);
const actualPagination = isAnEmptyOrFalsyObject(pagination) ? null : JSON.stringify(pagination);
const actualSearchText = !searchText ? null : searchText;
let shouldGo = false;
if (paramCondition !== actualCondition) {
if (actualCondition) {
url.searchParams.set('condition', actualCondition);
} else {
url.searchParams.delete('condition');
}
shouldGo = true;
}
if (paramPagination !== actualPagination) {
if (actualPagination) {
url.searchParams.set('pagination', actualPagination);
} else {
url.searchParams.delete('pagination');
}
shouldGo = true;
}
if (paramSearchText !== actualSearchText) {
if (actualSearchText) {
url.searchParams.set('searchText', actualSearchText);
} else {
url.searchParams.delete('searchText');
}
shouldGo = true;
}
if (shouldGo) goto(url, { replaceState: false, keepFocus: true, noScroll: true });
});
afterNavigate(({ to }) => {
if (!to) return;
const paramCondition = to.url.searchParams.get('condition');
const paramPagination = to.url.searchParams.get('pagination');
const paramSearchText = to.url.searchParams.get('searchText');
if (paramCondition && paramCondition !== JSON.stringify(condition)) {
condition = JSON.parse(paramCondition);
}
if (paramPagination && paramPagination !== JSON.stringify(pagination)) {
pagination = JSON.parse(paramPagination);
}
if (paramSearchText && paramSearchText !== searchText) {
searchText = paramSearchText;
}
if (firstLoad) firstLoad = false;
});