3

DISCLAIMER: I originally filed this as a bug in the Next.js github repo, but it was not recognised as an issue and was promptly closed. The explanation/solution that was given did not work for me so this means I must be doing something wrong, ergo the question here.

The question/problem

I have this demo app (codesandbox source here) which makes use of two Next.js routing features: Parallel routes and route interceptors

In short, clicking on a photo changes the URL from / to /photos/[id] but unless you reload the page, the photo is shown in a modal on top of the previous route view, instead of completely changing the page to the photo details page, which is neat.

Clicking the modal overlay invokes the router.back() function, which takes us one step back in the history stack, the URL changes to / and the photo modal is no longer shown, as expected.

Now, I have ended up with a scenario where I need to be able to navigate away from the modal with an actual Link component instead of calling router.back(). This means the user should be able to click the link that points away from /photos/[id], the URL should change to where the link is pointing and the modal should disappear.

However as you can see in the demo this is not the case.

What happens instead is the user clicks the link that points away from /photos/[id], the URL changes to where the link is pointing but the modal stays where it is. You can observe this behaviour even if you click on the link that takes you to a completely unrelated page.

Initially I thought maybe the problem is somehow the Link component and attempted to replace it with something like

    <button
      className="action"
      onClick={() => {
        router.push(`/`);
      }}
    >
      Close
    </button>

Yet it still does not work. It seems like invoking router.push('/') works somehow differently from router.back() even though both result in the URL changing to /.

If this somehow intended behaviour it is really strange, because apart from being counter intuitive, the docs themselves read

If a modal was initiated through client navigation, e.g. by using , you can dismiss the modal by calling router.back() or by using a Link component. (source)

The bolded part is what really throws me off.

As suggested in the comment left on the issue, I tried the solution with the [...catchAll] route; I tried moving it around from app/ to app/@modal/ to app/@modal/(..)photos/ and see in which dir it will work as described and it did not work.

So, is this a bug, or I am terribly misusing and misunderstanding something in the way the router and the router interception works?

If it's the latter how can you make the Link navigation work from intercepted routes?

Thanks.

Dimitris Karagiannis
  • 8,942
  • 8
  • 38
  • 63
  • For what its worth I'm running into this issue as well. Unclear how to dismiss a modal by navigating forward from the modal. – Danny May 17 '23 at 14:51
  • I have good news, turns out this was in fact an issue, and it got reopened, after being closed initially. I think they are currently working on it and should be fixed in one of the next patch versions – Dimitris Karagiannis May 18 '23 at 15:16
  • I had the same issue. I couldn't open your sandbox, but I wonder--are you using a Dialog element for your modal? I wonder if what's going on is the whole prerender thing with Next means that it really doesn't remove these elements, but instead tries to hide them with CSS or something? Dialog has its own CSS that might not play well with whatever Next is doing. – Amy Blankenship Jun 01 '23 at 20:45
  • @AmyBlankenship huh, weird, I am using the "share link" thing from codesandbox and it does not work :/ I don't know what's wrong. No, I was not using a dialog element for the Modal. It's a recognized issue though, you can follow its progress [here](https://github.com/vercel/next.js/issues/49662) – Dimitris Karagiannis Jun 02 '23 at 15:43
  • I just watched this video, which describes the feature differently than I understand it from the docs https://youtu.be/pTsmh36ZB8c – Amy Blankenship Jun 02 '23 at 16:06
  • @AmyBlankenship From what I saw from the video he is explaining it right – Dimitris Karagiannis Jun 02 '23 at 16:13

1 Answers1

1

Turns out this was in fact an issue with Next.js and the ticket I submitted which had been closed initially got reopened (see the link to the GitHub issue report in the question disclaimer). Should be fixed in one of the next patch versions updates of Next.js

Dimitris Karagiannis
  • 8,942
  • 8
  • 38
  • 63