Search code examples
reactjsnext.jsmodal-dialogurl-routing

Dynamic Modal routing with NextJS like Instagram


I am looking for someone to help me with the following issue:

I am trying to implement a modal system where the modals are dependent on the route using NextJS.

So say I am on the following page:

website.com/help

and say I have the modals category1, category2, and category3, all of which I would prefer to be able to persist after closing them (they are loading iframes), however this is not a must.

Then I would want the routes for these modals to be:

website.com/help/category1
website.com/help/category2
website.com/help/category3

I have already found this in the official NextJS examples: with-route-as-modal

But the problem I am having is that with queryString routing, when you reload/visit the modal route directly, the modal wont be used. So the content will become full screen (it is a page of its own).

With dynamic routing, this is not an issue, since if you visit the modal route directly the modal will be kept. But the problem I am having with this is that these modals aren't exactly modals, the original page "behind" the modal just becomes the body background. The other issue is that I wont be able to persist these.

Here is the demo on stackblitz:

https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-route-as-modal?file=README.md

I would appreciate anyone helping me with this so much because it has really driven me mad trying to solve this!


Solution

  • I have a solution that you may like. For the example you provided you only need to import <Grid/> in /article/[articleId].js like it's done in /index.js

    so when you open the modal the articles/posts list is shown in the background

    // article/[articleId].js
    import Grid from '../../components/Grid';
    
    <>
       <Modal
            isOpen={true}
            onRequestClose={() => router.push('/', undefined, { scroll: false })}
            contentLabel="Post modal"
       >
            <Article id={articleId} pathname={router.pathname} />
       </Modal>
       <Grid />
    </>
    

    don't forget to give scroll false in router.push() and <Link/> so when you go back to articles/posts list it doesn't jump to the top of the page

    router.push('/', undefined, { scroll: false })
    
    <Link 
          key={index}
          href="/article/[articleId]"
          as={`/article/${id}`}
          scroll={false} 
    >
          <a className={styles.postCard}>{id}</a>
    </Link>
    

    you can see an example here: https://stackblitz.com/edit/github-rkrovd