How to Remove a Single Parameter from a URL in Next.js 14?
Answered
Mackenzie River Husky posted this in #help-forum
Mackenzie River HuskyOP
Hi everyone, I'm relatively new to Next.js, and I have a question regarding how to manipulate multiple search parameters using useRouter and Link while keeping the rest intact and having a dynamic URL. For example, I have a URL like this: http://localhost:3000/admin?menu=topping where I store one parameter for the menu I want to display, and I have another parameter which, if something is modified on the server, returns either an error or a success message in the URL like this: http://localhost:3000/admin?menu=topping&message=success. This brings up a pop-up successfully, and once it's closed, I want to remove the message from the URL while keeping menu=topping. Is this possible somehow? Unfortunately, I couldn't find any examples in the documentation where multiple parameters are demonstrated. One attempt I made was:
const handleClose = () => {
setIsPopperOpen(false);
setPopperDanger(false);
if (urlMessage) {
router.replace('?message=none');
}
};
But unfortunately, this deletes the entire URL along with the menu. What would be the correct solution for this? Is it common practice to store errors or successful messages in the URL in Next.js? I would greatly appreciate it if someone could shed some light on this. I've watched quite a few YouTube videos on the topic, but unfortunately, they only cover the basics everywhere.
(I created this because then I only need to fetch the data once in the page component and can pass it to every menu as a prop.)
Thank you in advance.
const handleClose = () => {
setIsPopperOpen(false);
setPopperDanger(false);
if (urlMessage) {
router.replace('?message=none');
}
};
But unfortunately, this deletes the entire URL along with the menu. What would be the correct solution for this? Is it common practice to store errors or successful messages in the URL in Next.js? I would greatly appreciate it if someone could shed some light on this. I've watched quite a few YouTube videos on the topic, but unfortunately, they only cover the basics everywhere.
(I created this because then I only need to fetch the data once in the page component and can pass it to every menu as a prop.)
Thank you in advance.
Answered by Ray
or this
const searchParams = useSearchParams()
const newSearchParams = new URLSearchParams(searchParams)
newSearchParams.delete('message')
router.replace("?" + newSearchParams.toString());10 Replies
or this
const searchParams = useSearchParams()
const newSearchParams = new URLSearchParams(searchParams)
newSearchParams.delete('message')
router.replace("?" + newSearchParams.toString());Answer
Mackenzie River HuskyOP
Thank you very much! May my gratitude follow you. I've been pondering over this problem for days now, and you've saved me, the second code works perfectly! How can the same be achieved with the Link component? 🔥
@Mackenzie River Husky Thank you very much! May my gratitude follow you. I've been pondering over this problem for days now, and you've saved me, the second code works perfectly! How can the same be achieved with the Link component? 🔥
you could create a function which return the url string
const searchParams = useSearchParams()
function renderHref() {
const newSearchParams = new URLSearchParams(searchParams);
newSearchParams.delete("message");
return "?" + newSearchParams.toString();
}
return (
<Link href={renderHref()}></Link>
)Mackenzie River HuskyOP
Thank you very much, I'll try this as well, but I have one last question if possible.
Here's the translation:
Is it possible to achieve this dynamically on the server-side/server action as well? I mean, could it insert the "message" parameter after the existing URL? So instead of having to write it out like this:
if (error) {
return redirect(
}
return redirect(
Could it be done something like this?
return redirect(
And then insert the current URL in front of the message on the frontend. This would be beneficial because then I could dynamically integrate the mentioned error handling throughout the entire application without having to specify the beginning of the expected URL in every server action.
Here's the translation:
Is it possible to achieve this dynamically on the server-side/server action as well? I mean, could it insert the "message" parameter after the existing URL? So instead of having to write it out like this:
if (error) {
return redirect(
/admin?menu=topping&message=${error.message}&error=true);}
return redirect(
/admin?menu=topping&message=success);Could it be done something like this?
return redirect(
/{"insert here"}?message=success)And then insert the current URL in front of the message on the frontend. This would be beneficial because then I could dynamically integrate the mentioned error handling throughout the entire application without having to specify the beginning of the expected URL in every server action.
@Mackenzie River Husky Thank you very much, I'll try this as well, but I have one last question if possible.
Here's the translation:
Is it possible to achieve this dynamically on the server-side/server action as well? I mean, could it insert the "message" parameter after the existing URL? So instead of having to write it out like this:
if (error) {
return redirect(`/admin?menu=topping&message=${error.message}&error=true`);
}
return redirect(`/admin?menu=topping&message=success`);
Could it be done something like this?
return redirect(`/{"insert here"}?message=success`)
And then insert the current URL in front of the message on the frontend. This would be beneficial because then I could dynamically integrate the mentioned error handling throughout the entire application without having to specify the beginning of the expected URL in every server action.
try creating a helper function like this
function redirectWithMessage(
url: string,
params: Record<string, string> = {
message: 'success'
},
) {
const qs = new URLSearchParams();
for (const [k, v] of Object.entries(params)) {
qs.append(k, v);
}
qs.sort();
redirect(`/${url}?${qs.toString()}`);
}Mackenzie River HuskyOP
So if I understand correctly, Next.js technologically isn't capable of this, right? Like in the case of router.replace where you provided the '?'? Thanks for the help, greatly appreciated. You saved me from hours of further searching!
@Mackenzie River Husky So if I understand correctly, Next.js technologically isn't capable of this, right? Like in the case of router.replace where you provided the '?'? Thanks for the help, greatly appreciated. You saved me from hours of further searching!
yeah,
router.replace() is expecting you pass in a stringMackenzie River HuskyOP
Thank you!
np