N
Nuxt9mo ago
Fabian B.

Reactive Route Search Query Composable

Does somebody have deeper experience with this? I am trying to implement a composable to reactively use a route search query. Meaning that the value updates reactively whenever the route query parameter changes. And when setting a new value with .value, it does a navigateTo() in the background. However, there are issues with SSR, which makes it hard to implement this. This is how I got so far:
export const useRouteSearchQuery = ({
name = "q",
defaultValue = "",
replace = false,
}: { name?: string; defaultValue?: string; replace?: boolean } = {}) => {
const requestUrl = useRequestURL();
const route = useRoute();

const searchQuery = computed({
get: () => {
console.log("-> getter", {
routeVal: route.query[name],
staticVal: requestUrl.searchParams.get(name),
});

// Reactive, but doesnt work in ssr
const routeVal = route.query[name];
if (routeVal) return String(routeVal);

// Non reactive, works in ssr
const staticVal = requestUrl.searchParams.get(name);
if (staticVal) return String(staticVal);

return defaultValue;
},
set: (newVal: string | undefined) => {
const query = { ...route.query };
if (newVal?.length) {
query[name] = newVal;
} else {
delete query[name];
}

navigateTo({ query }, { replace });
},
});

return { searchQuery };
};
export const useRouteSearchQuery = ({
name = "q",
defaultValue = "",
replace = false,
}: { name?: string; defaultValue?: string; replace?: boolean } = {}) => {
const requestUrl = useRequestURL();
const route = useRoute();

const searchQuery = computed({
get: () => {
console.log("-> getter", {
routeVal: route.query[name],
staticVal: requestUrl.searchParams.get(name),
});

// Reactive, but doesnt work in ssr
const routeVal = route.query[name];
if (routeVal) return String(routeVal);

// Non reactive, works in ssr
const staticVal = requestUrl.searchParams.get(name);
if (staticVal) return String(staticVal);

return defaultValue;
},
set: (newVal: string | undefined) => {
const query = { ...route.query };
if (newVal?.length) {
query[name] = newVal;
} else {
delete query[name];
}

navigateTo({ query }, { replace });
},
});

return { searchQuery };
};
Works in most cases, but in the case where I do a navigateTo() in any component (or the user is navigating back & forth) where certain query parameters are getting removed (e.g. from ?foo=bar&xyz=abc to ?foo=bar), it's still not reactive (watching the searchQuery value reacts to changes in the query parameters, not not when it gets removed e.g. from the user navigating back & forth).
1 Reply
Fabian B.
Fabian B.OP9mo ago
I solved it by just using useRoute().query.q and navigateTo({ query: { ...useRoute().query, q: '...' } }) directly in my components. I wanted to avoid it to reduce boilerplate, but it seems like it comes with too many issues. However, if someone has developed something like this that works better, I would be happy to try it out!
Want results from more Discord servers?
Add your server