next.js: Intercepting Routes do not close on navigation with `router.push` or `` in Next.js

Link to the code that reproduces this issue

https://github.com/hqw567/nextgram

To Reproduce

Steps to reproduce the behavior:

  1. Set up an Intercepting Route in a Next.js application.
  2. Navigate to the page that triggers the Intercepting Route.
  3. From the Intercepting Route, use router.push('/') or a <Link href={'/'}> element to navigate back to the home page.
  4. Notice that the Intercepting Route does not close or unmount as expected.

https://github.com/vercel/next.js/assets/74847198/ec0a21cf-3d34-4c5d-9e64-4d53bf45c88e

Current vs. Expected behavior

Current Behavior: When navigating away from an Intercepting Route using router.push('/') or <Link href={'/'}>, the Intercepting Route’s component does not unmount or close, leaving the Intercepting Route’s state or UI still active or visible in the background.

Expected Behavior: Upon navigating away from an Intercepting Route using either router.push('/') or a <Link href={'/'}>, the Intercepting Route’s component should unmount and close properly, similar to how it behaves when using router.back(). This ensures a consistent and predictable navigation experience within Next.js applications.

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro for Workstations
  Available memory (MB): 16070
  Available CPU cores: 12
Binaries:
  Node: 20.11.0
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 14.1.1-canary.70 // Latest available version is detected (14.1.1-canary.70).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local)

Additional context

No response

About this issue

  • Original URL
  • State: closed
  • Created 4 months ago
  • Reactions: 3
  • Comments: 17 (5 by maintainers)

Most upvoted comments

Hi @hqw567 and @steve-marmalade – since catch-all routes ([...route]) match everything except the index route (ie, /foo/bar, /foo/bar/baz, but not /foo), and you’re linking back to the root page, you’d ideally use an optional catch-all route here ([[...route]]). This would include the index route. However, parallel routes don’t yet support optional catch-all segments (but it’s being tracked here).

In the meantime, you can work around this by having a @modal/page.tsx component that returns null. I tested that with your provided reproduction and it appears to have worked as you expect.

@ztanner , thanks for the quick response and the additional context! unfortunately, this didn’t immediately help me, since in my application I am routing to a non-index route and still seeing the modal stay open (which it sounds like should be covered by the regular [...catchAll] route).

I will try to modify the nextgram repo to see if I can easily reproduce.

Hi - as mentioned by @xvvvyz, the catch-all route is the correct way to handle this, and the docs link provided above explains why it behaves this way.

Going to close this out but don’t hesitate to ask any follow-up questions if you have any 😃

Hi @ztanner, I tried using the catch-all route you mentioned, but it didn’t work at all.

https://github.com/hqw567/nextgram/commit/f0eeac350c26e428b1c2ccf67884e2fb79e32a5d

they managed to break the router again. insane

@ztanner , thanks for the quick response and the additional context! unfortunately, this didn’t immediately help me, since in my application I am routing to a non-index route and still seeing the modal stay open (which it sounds like should be covered by the regular [...catchAll] route).

I will try to modify the nextgram repo to see if I can easily reproduce.

I’m having a similar problem. The slot route is not being unmounted after I navigate to a different non-index route. I’ve tried, default pages, null pages and catch all routes. No luck here.

Looks like you don’t have a catch-all route in your @modal slot. Read:

https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#closing-the-modal