I’m working with Next.js and have the following routes:
/@modal/(.)snippets/[id]/page.tsx
(for a modal)/snippets/[id]/page.tsx
(for individual snippets)/snippets/new/page.tsx
(for creating a new snippet)
The problem occurs when I navigate to /snippets/new
— instead of opening the new snippet creation page, the modal for /@modal/(.)snippets/[id]
is opened instead.
I believe this is happening because new might be interpreted as an id, which causes the modal to open.
Question:
How can I ensure that navigating to /snippets/new
opens the new snippet creation page, without triggering the modal meant for /@modal/(.)snippets/[id]
? What is the best way to handle this in Next.js when using parallel routes?
Here is my project structure:
2
Answers
The issue you’re experiencing occurs because Next.js is trying to match /snippets/new with the [id] dynamic route. This happens because dynamic routes like [id] will match any value, including new. To avoid this, you need to explicitly define the /snippets/new route as a static route that takes precedence over the dynamic [id] route. Here’s how you can handle this using parallel routes and Next.js routing conventions:
In this setup, new/page.tsx is explicitly defined, and [id]/page.tsx should only match when the path isn’t /snippets/new.
Or You can use Conditional Rendering in [id]/page.tsx
If the structure above doesn’t resolve the issue, you can add conditional logic within [id]/page.tsx to render the appropriate component or redirect based on the id value.
Potential Cause: Route Conflict
The intercepting route
@modal/(.)snippets/[id]
may be causing a conflict with/snippets/new
because both are defined under the/snippets
route. Since Next.js is designed to match routes as they are navigated, it’s possible that the router is interpreting/snippets/new
in a way that prioritizes the modal route.Solution 1: Use a
layout.tsx
to Separate RoutesIf you are handling modals and pages within the same section, you can further separate these using a layout that handles the different experiences. This way, modals and static routes like
/new
can be treated separately.and this is the example code:
snippets/layout.tsx
: Handles the main layout for/snippets
and its children.@modal/(.)snippets/[id]/page.tsx
: Will only activate when the modal route is explicitly used, such as/@modal/(.)snippets/1
, avoiding interference with the static/snippets/new
page.Solution 2: Make Modals Optional (Controlled at Route Level)
Make sure that the modal route only activates when it is explicitly invoked, when a modal needs to be opened
(/@modal/(.)snippets/1).
This avoids accidental modal rendering on/snippets/new
.In your app, you can conditionally show the modal based on the actual route, making sure that
/new
doesn’t trigger modal logic. You could control this by checking the pathname and rendering the modal only when necessary.