Next.js: modal with url like reddit or twitter. changing url without navigation.

Created on 18 Jul 2019  Â·  15Comments  Â·  Source: vercel/next.js

Feature request

On Reddit or twitter, if you click on a post, it will change url to post view url, but it shows post on modal instead of navigating and losing current ui contexts (scroll positions and such).
I don't think this modern behavior is currently supported by Next.js

Describe the solution you'd like

  1. Click on a list item to view list item content details.
  2. Show item details on modal and change url
  3. closing modal pops url
  4. all previous ui contexts are preserved (scroll positions, etc.)

  5. when user lands on the item detail url (initial load), it should show item detail page (not modal)

All modern websites implement this behavior for better viewing experience

good first issue example

Most helpful comment

I think there's a simpler solution than what's been described above so far. I posted a quick half-baked demo of it here: https://github.com/exogen/next-modal-pages

This solution should definitely be improved upon, but the basic idea is sound:

  • In Next.js, routing to another page occurs by unmounting the previous page component and mounting the next one.
  • A custom <App> lets you decide exactly what to do with these page components. For example, you could wrap them in some layout or provider components in _app.js.
  • You also don't necessarily need to unmount the previous pages just because you're being given a new one in the App's latest render call. You could save a history of the previous page component/props and continue to render those if you want.
  • So, this page modal behavior can be accomplished by remembering a "stack" of previous page component/props passed to App, and rendering them as nested modals.

My demo does this in a somewhat janky way, but you get the idea. You don't need to mess with browser history or the DOM directly – Next.js and React already give you the pieces you need. From Next.js' perspective, you are still on the new page and rendering that page's component, it's just that the app has chosen to dynamically render other stuff around the current page as well – like the pages from past renders.

Edit: I've updated the demo with a cleaner implementation. :)

All 15 comments

There is an attempt by @singlepageprogrammer for this behavior: https://github.com/zeit/next.js/pull/7864
Problem is using window.history breaks Next router.
Using Next router triggers a navigation.

I've asked a similar question here: https://spectrum.chat/next-js/general/what-is-the-best-way-to-create-the-instagram-photo-modal-routing-experience-on-dynamic-pages-with-next-9~5695efed-d505-446b-8474-1ce2117e19d0

In theory it's as simple as "basically you don’t link to another page at all when you open the modal, you just display the modal on the current page and manually push a new history entry using Next’s router API." - https://mobile.twitter.com/adamwathan/status/1147593450734444547

But not sure how to do this in a Next.js ordained way.

To add some of our experience to this from Weedmaps. We ran into issues with Mobile Chrome and Mobile Safari and their attempts to cache resources when navigating back in the browser. So when pushing a route and opening a modal, X set of JS resources (page bundles, etc) have been loaded and executed. Then if you navigate away, then click "back" it attempts a full round trip to the Server, loads Y JS bundle for the full detail page, but also re-loads the old JS from the cache, and then the in-correct X bundle attempts to hydrate the page, and things break.

We tried a few tricks to prevent the browser from loading the cached resources, to no avail.

Our solution was to use a custom routing solution to ensure both routes loaded the same JS resources, but then bifurcated the rendering path based on URL

I think there's a simpler solution than what's been described above so far. I posted a quick half-baked demo of it here: https://github.com/exogen/next-modal-pages

This solution should definitely be improved upon, but the basic idea is sound:

  • In Next.js, routing to another page occurs by unmounting the previous page component and mounting the next one.
  • A custom <App> lets you decide exactly what to do with these page components. For example, you could wrap them in some layout or provider components in _app.js.
  • You also don't necessarily need to unmount the previous pages just because you're being given a new one in the App's latest render call. You could save a history of the previous page component/props and continue to render those if you want.
  • So, this page modal behavior can be accomplished by remembering a "stack" of previous page component/props passed to App, and rendering them as nested modals.

My demo does this in a somewhat janky way, but you get the idea. You don't need to mess with browser history or the DOM directly – Next.js and React already give you the pieces you need. From Next.js' perspective, you are still on the new page and rendering that page's component, it's just that the app has chosen to dynamically render other stuff around the current page as well – like the pages from past renders.

Edit: I've updated the demo with a cleaner implementation. :)

In my case, I don't want or need to change anything but the browser's url.

@timneutkens Is there an official recommended/blessed way to do this, maybe like @exogen's example?

I have found this but it asks for changes in next js module

https://github.com/tomevans18/nextagram

Any official recommended examples?

https://codesandbox.io/s/ecstatic-buck-2t2tr

I am able to do this on / but on dynamic route its not possible.

Can confirm, changing if (!routeMatch) { to if (false) { in node_modules/next/dist/next-server/lib/router/router.js makes the use of model to dynamic pages possible. It works beautiful now.

Is there already a good solution? I tried hashchange - but it does not work

https://github.com/mohammad-amin-hesam/react-modal-route-example

On Fri, 20 Mar 2020 at 16:02, FabianL1 notifications@github.com wrote:

Is there already a good solution? I tried hashchange - but it does not work

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/zeit/next.js/issues/8023#issuecomment-601676415, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/ALEL5N5LBEHZWZLR42CH643RINO4JANCNFSM4IEWM7IQ
.

This should be closed?

Landed #11473

Is there any way to show modal (not item detail page) when user lands on the item detail url (initial load) in opposition to the last step of described in https://github.com/zeit/next.js/issues/8023#issue-469543180 ?
AFAIK, reddit behaves like this now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sospedra picture sospedra  Â·  3Comments

ghost picture ghost  Â·  3Comments

wagerfield picture wagerfield  Â·  3Comments

timneutkens picture timneutkens  Â·  3Comments

flybayer picture flybayer  Â·  3Comments