next.js: Intercepting parallel routes including dynamic route not working within the same directory
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 22.5.0: Thu Jun 8 22:22:22 PDT 2023; root:xnu-8796.121.3~7/RELEASE_X86_64
Binaries:
Node: 18.16.1
npm: 9.8.0
Yarn: 1.22.19
pnpm: N/A
Relevant Packages:
next: 13.4.10-canary.3
eslint-config-next: 13.4.9
react: 18.2.0
react-dom: 18.2.0
typescript: 5.1.6
Next.js Config:
output: N/A
Which area(s) of Next.js are affected? (leave empty if unsure)
App Router
Link to the code that reproduces this issue or a replay of the bug
https://github.com/zoogeny/next-js-interceptor-parallel-dynamic
To Reproduce
Checkout, install the project and run the dev server
git checkout https://github.com/zoogeny/next-js-interceptor-parallel-dynamic.git
cd next-js-interceptor-parallel-dynamic
npm install
npm run dev
Load a page in the blog (e.g. http://localhost:3000/blog/first-post) and you will see a basic interface:
params.slug: first-post
Same dir
Nested dir
If you click the Nested dir
link you will correctly get a parallel slot rendered below the links with a red border. If you click within the border the slot will be removed.
If you click the Same dir
link you will navigate the entire page. This is not expected - it should be intercepted and render inside the parallel slot.
Describe the Bug
It appears that interception of routes within the same directory does not work. e.g. I have a directory structure as follows:
app
/blog
/[slug]
page.tsx
/@modal
/(.)[slug]
page.tsx
/(.)summary
/[slug]
page.tsx
default.tsx
layout.tsx
page.tsx
While I am on the blog/some-page
page I can intercept <Link>
to blog/summary/another-page
but I cannot intercept <Link>
to blog/another-page
.
Expected Behavior
When on a page blog/some-page
I would expect to be able to intercept <Link>
to blog/another-page
using a folder at blog/@modal/(.)[slug]
.
The purpose of this is to show summary modals for blog entries without navigating away from the current page.
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 21
- Comments: 25 (5 by maintainers)
Commits related to this issue
- Update README.md Match the issue posted on https://github.com/vercel/next.js/issues/52533 — committed to zoogeny/next-js-interceptor-parallel-dynamic by zoogeny a year ago
- interception routes: fix interception for dynamic routes (#58198) This PR fixes the bug in which interception routes of the form `(.)[param]` would not intercept navigations. The bug happened becaus... — committed to vercel/next.js by feedthejim 8 months ago
FORWARD: #49614
Facing the same issue with the following structure; (v13.4.9)
And on top of that; the
locale
param becomes undefined when visiting the routeStill an ongoing issue it looks like.
So if I want
section/25/edit
you would expect to utilize this folder structure based on the Next convention in the docs:But this doesn’t work. So instead we are left with what appears to be a few workarounds:
Work around 1:
You use (…) root segment as rodrigomf24 mentioned above: https://github.com/vercel/next.js/issues/52533#issuecomment-1735258750. Your folder structure now looks like so:
This solution is more akin to an absolute path. It isn’t terrible if you don’t have to traverse a long root app path in your @slot.
In my case my section actually lives much further down the route hierarchy so this just isn’t worthwhile to nest segments so deeply under @modal. There is also the risk that it breaks if you add additional folder structures between the root and this without accounting for it.
Work around 2:
You use (…) instead of (…). This solution keeps that pesky section folder reference in our @modal but acts more like a relative path.
Perhaps the biggest downside is it isn’t as intuitive as it could be because it feels like we are breaking what should be the standard Next convention in the original example because I’d expect (…) to move me up two segments for example. And it kinda is but it feels a bit confusing or not as clear as it could be since you have to maintain the parent folder.
Workaround 3:
You avoid having (.) on a dynamic segment. You can achieve this with a nested folder like so.
IvanRomanovski touches on this in his comment: https://github.com/vercel/next.js/issues/52533#issuecomment-1735258750 even though his example is slightly different than mine.
This approach feels more in line with the Next convention but comes with a more polluted route path for users. It also might be difficult to come up with a nested segment for your use case.
Hopefully someone can tackle the core issue and allow dynamic segments to act as intercepted routes e.g)
(.)[id]
. For now these seem like the best solutions to working around this problem. If you spot any issues or typos with the solutions I’ve gathered to help save someone the hours of headache troubleshooting, let me know and I’ll edit them.thanks to everyone here for helping me work through this problem!
@Netail try to add a error handler
I achieved this repeating the structure inside modal for each language (I only have a small set of language, hope the same for you ATM)
Hope it helps, little tricky but for now it does the job!
I managed to fix this problem, solution: I created the parallel route
@modal
outside the hidden route(views)
and just placed the dynamic route following the same path, directly, without saying that it is inside the(views)
route, this way it will actually be intercepted, this way I can normally call it/project/id
.I tested several ways, and I saw that calling the
@modal
route inside the(views)
route was calling both routes at the same time, and the other way was calling the route but the component was not being used intercepted.I hope this can help others with the same problem.
I could not get route matching to work with routes that started with dynamic parameter, eg. /[lang]/, but it did work if it started with static name , e.g. /locale/[lang].
This did not work me:
But this did:
Its probably just a regex happening behind the scenes between path and (.)whatever, so I am not surprised dynamic matching does not work…
I’m having the same issue with the following folder structure:
The following does work:
But this intercepts the route from pages outside of the [post] route group as well, which is not desired for our use case.
Alright found the issue which triggers the issue; generateStaticParams. Created a seperate issue for this; #52880
Same issue here. I’m using next-intl and can’t show modal with intercepted routes yet.