How to Open a Modal Based on URL in Next.js Without Full Page Reload
Unanswered
Pond loach posted this in #help-forum
Pond loachOP
I’m trying to replicate a modal behavior in Next.js similar to Twitter’s /compose/post feature:
Clicking a button changes the URL (e.g.,
Closing the modal should revert the URL (e.g., back to
If the page is refreshed while the modal is open (
I want to achieve this without using query parameters (e.g.,
What is the best way to implement this in Next.js while maintaining good UX and performance?
Clicking a button changes the URL (e.g.,
/compose/post) and opens a modal while keeping the feed (background content) visible.Closing the modal should revert the URL (e.g., back to
/).If the page is refreshed while the modal is open (
/compose/post), the modal should remain open, and the feed should still be visible in the background.I want to achieve this without using query parameters (e.g.,
?modal=true). Instead, I want to use proper route paths like /compose/post.What is the best way to implement this in Next.js while maintaining good UX and performance?
42 Replies
@Pond loach I’m trying to replicate a modal behavior in Next.js similar to Twitter’s /compose/post feature:
Clicking a button changes the URL (e.g., `/compose/post`) and opens a modal while keeping the feed (background content) visible.
Closing the modal should revert the URL (e.g., back to `/`).
If the page is refreshed while the modal is open (`/compose/post`), the modal should remain open, and the feed should still be visible in the background.
I want to achieve this without using query parameters (e.g., `?modal=true`). Instead, I want to use proper route paths like `/compose/post`.
What is the best way to implement this in Next.js while maintaining good UX and performance?
Daggertooth pike conger
if you have a model component, you can make the model accessible anywhere in the directory, using a provider for example what u then want to do is when the modal is open you want to push the new url to the history api, this url will be dispalyed in the url but actually isnt the page ur on basically, then you can have the /compose/post page have the component to automatically open the modal
this leads to behaviour
when i press "post" it opens the modal as normal but also pushes /post/compose to the history api
if i manually visit /post/compose it will still automatically open the modal
when i press "post" it opens the modal as normal but also pushes /post/compose to the history api
if i manually visit /post/compose it will still automatically open the modal
pushing the url to the history api wont refresh the content on the page fyi
for example
lets say this component is used in
/ pageto push to
/post/compose u would doasync function event() {
history.pushState({}, '', '/post/compose')
postModalOpen(true)
}but on the actual
/post/compose pageyou would render the post feed along with the modal
so if the post feed is a component
its just the same as the
/ page but you automatically open the modaland u can use history for push back too
pretty sure
@Daggertooth pike conger if you have a model component, you can make the model accessible anywhere in the directory, using a provider for example what u then want to do is when the modal is open you want to push the new url to the history api, this url will be dispalyed in the url but actually isnt the page ur on basically, then you can have the /compose/post page have the component to automatically open the modal
Pond loachOP
I tried using
It seems
router.push(/compose/post). But it was requesting for new page. It seems
history api is only updating the URL without requesting for a new page. Let me give it a try and update here, thanks!@Pond loach I tried using `router.push(/compose/post)`. But it was requesting for new page.
It seems `history` api is only updating the URL without requesting for a new page. Let me give it a try and update here, thanks!
Daggertooth pike conger
the history api shouldnt be requesting a new page
thats the point
you should have the post modal as a provider where u can have a function to open it from any page
then when you push the url with history api you can open the modal with the function
and do the same on the actual url page
have another file at
/src/app/compose/post/page.tsx but this file will automatically open the post modaland also render the feed
if required
however, if i open the post modal from
/ the feed will stay the same, but if i refresh the page on compose post the feed will re-generate if you have a algorithm or whatever code that changes the feed, i.e order etcthis is normal and even happens on twitter, if you open post modal from /home it will keep the feed the same but if you go to compose post and refresh the page the feed will change
Daggertooth pike conger
@Pond loach working?
Daggertooth pike conger
although
before like the guy said abt routing
that works
its also possible to do
router.push('url', undefined, { shallow: true })with defined router obv
Pond loachOP
@Daggertooth pike conger sorry for late reply
it was late here so i slept.
I tried history api. it works perfectly.
however
I was using router from
nextjs documentation also seems out of date https://nextjs.org/docs/pages/building-your-application/routing/linking-and-navigating#shallow-routing
it was late here so i slept.
I tried history api. it works perfectly.
however
router.push('url', undefined, { shallow: true } this does not workI was using router from
router/navigation and it seems it no longer supports shallow config optionnextjs documentation also seems out of date https://nextjs.org/docs/pages/building-your-application/routing/linking-and-navigating#shallow-routing
Pond loachOP
my bad, the above doc link is gor pages router.
here the link of the app router, but it seems they do not support shallow routing anymore: https://nextjs.org/docs/app/api-reference/functions/use-router
here the link of the app router, but it seems they do not support shallow routing anymore: https://nextjs.org/docs/app/api-reference/functions/use-router
Rose-breasted Grosbeak
Uhm, does parallel routes not work for your case?
Pond loachOP
@Rose-breasted Grosbeak no, I wanted to change the URL also, that's why
Pond loachOP
I could technically do it with intercepting route. but then feed would refresh because I will have to render totally different page
when post button is clicked I did not want to refresh the feed, just change the URL and open the modal
updating the URL with shallow option is perfect solution for this.
when post button is clicked I did not want to refresh the feed, just change the URL and open the modal
updating the URL with shallow option is perfect solution for this.
Rose-breasted Grosbeak
Intercepting routes along with parallel do just that, except the modal would be a new page on reload. (Which is really weird)
https://github.com/vercel-labs/nextgram
Overriding the history API may cause issues with next router
https://github.com/vercel-labs/nextgram
Overriding the history API may cause issues with next router
@Rose-breasted Grosbeak Intercepting routes along with parallel do just that, except the modal would be a new page on reload. (Which is really weird)
https://github.com/vercel-labs/nextgram
Overriding the history API may cause issues with next router
Pond loachOP
yeah, i wanted to replicate x behaviour. I didn't want new page with just the modal and no feed in the background that's the reason i didn't use intercepting route
@Pond loach yeah, i wanted to replicate x behaviour. I didn't want new page with just the modal and no feed in the background that's the reason i didn't use intercepting route
Rose-breasted Grosbeak
just be sure, that would happen when the user reloads the page. the background would maintain its state without a manual page reload