I'm filtering results from an API utilizing query parameters in my Next.js app. I want to use useRouter()
to push multiple different filters with the same key, so my query params could look like:
?page=1&skill=html&skill=css&skill=js
And I can pass each of those parameters to my API request. Right now, when I'm trying to add a skill parameter I'm using router.push
to do it, like this:
const router = useRouter();
const addFilter = (skill: string) => router.push({ query: { ...router.query, skill: skill.toLowerCase() } });
But obviously it's overwriting the previous skill, so I'm only ever getting one of them in the URL. How can I go about adding additional query parameters with the same key, preferably using useRouter()
or next/router
?
To manipulate the query params in the URL in Next.js I use a custom hook that uses what useRouter offers, but I also add some util methods, in this case, to add a filter to the URL I have the method addParam.
This is the body of the custom hook.
const useRouterFilter = () =>{
const { pathname, query, push } = useRouter()
return {
addParam,
...
}
}
And this would be the addFilter method inside the hook:
/**
* Adds a query param to the URL string. Multiple params with the same name
* and different values can be added.
* @param name The name of the param.
* @param value The value of the param.
*/
const addParam = (name: string, value: string | boolean | number) => {
const { [name]: param, ...rest } = query
let newQuery
if (!param) {
newQuery = { ...rest, [name]: encodeURIComponent(value) }
} else if (Array.isArray(param)) {
if (param.indexOf(encodeURIComponent(value)) > -1) return
newQuery = { ...rest, [name]: [...param, encodeURIComponent(value)] }
} else {
if (param === encodeURIComponent(value)) return
newQuery = { ...rest, [name]: [param, encodeURIComponent(value)] }
}
push(
{
pathname,
query: newQuery,
},
undefined,
{ shallow: true }
)
}
In this case I use push
to add the parameters to the URL, but replace
could also be used.
The full hook can be copied from the following Gist