#Problem with Next.js Interception route
88 messages · Page 1 of 1 (latest)
🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord
🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize
✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)
It sounds like you don't want an interception route at all. When you refresh the page, you want it to show the modal on top of the same [id]/page.tsx?
In that case, you don't need to use interception route, btw if you wanna still use that, you can implement the modal(open) in the default.tsx.
If that is the case, the modal route needs to know the [id] as well. I think the best way to do so is with parallel routes, putting the modal at /[id]/modal or something like that.
app/
├─ [id]/
│ ├─ layout.tsx
│ ├─ page.tsx
│ ├─ @modal/
│ │ ├─ default.tsx
│ │ ├─ modal/
│ │ │ ├─ page.tsx
in the default parallel route, render nothing. In the modal/ one, render the modal.
@acoustic knot
Why I have to use modal/page.tsx? Can I use page.tsx directly in @modal?
no; @modal creates the parallel route, meaning [id]/layout.tsx will get an additional param called modal containing whatever routes match in @modal. That's why you have @modal/default.tsx and @modal/modal/page.tsx. The route is what maters for the URL. if you wanted the modal at [id]/login or [id]/edit you would use @modal/login/page.tsx or @modal/edit/page.tsx instead.
I forgot to mention the [id]/layout.tsx file. You would change it to render both children and modal.
What will be the url to access that modal in that case?
[id]/modal, [id]/login, or [id]/edit depending on the contents of the @modal folder. See the parallel routes page for more info https://nextjs.org/docs/app/building-your-application/routing/parallel-routes
I also may be wrong here; I'm not sure the behavior of parallel routes on the [id]/page.tsx
Maybe the reason why you want to use interception route is route.
@acoustic knot, in your case, the modal should be removed in the @modal.
app/
├─ [id]/
│ ├─ layout.tsx
│ ├─ page.tsx
│ ├─ @modal/
│ │ ├─ page.tsx
in that case, the modal would always show.
This is the my project structure
Unless you added conditional rendering to it or something. Prince, can you explain what you want the end result to be?
So I want to show modal over work-requests/page.tsx
And when they refresh?
Still shows modal when refresh
still shows the modal over the same [codename]/[id]?
or, just shows the modal over the work requests page?
[codename]/[id] is modal route. I want to show that modal on work-requests/page.tsx when refresh
ok. So, user is on work-requests, goes to work-requests/[codename]/[id], and you want it to show a modal over the top of the work-requests page. Then, when they refresh or directly visit work-requests/[codename]/[id], it should still show the modal over the work-requests page?
Corret
@icy cypress, so in that case, what do you want to show when the user click history back?
In this case, I think what I explained earlier is correct. So, you would:
- make a folder
work-requests/@modal - move your
[codename]/[id]into that folder - add a
default.tsxto that folder that renders nothing - Add
work-requests/layout.tsx, which will recieve props{ children, modal}and render both.
work-requests page or work-requests/[codename]/[id] page with hidden modal?
When you visit work-requests, the layout will recieve whatever work-requests/@modal/default.tsx renders, and will recieve work-requests/page.tsx for children.
When you visit work-requests/[codename]/[id], layout will recieve whatever work-requests/[codename]/[id]/page.tsx renders for modal, and work-requests/page.tsx for children.
So if you want to show the modal still even the user refresh the current page.
You have to implement the opened modal in the default.tsx.
And for this you have to use interception route.
I tried this but it didn't work
I don't think that's what they're asking Demi. It sounds like there is no modal when they are on work-requests and only when at work-requests/[codename]/[id] should a modal appear, specifically ABOVE whatever work-requests is showing, and should remain even when refreshing.
@acoustic knot, you forgot to mention about the interception route.
I want to show work-requests/page.tsx when history back
Demi, I dont think an interception route is appropriate, because it should render the SAME thing regardless of how it's reached.
Let's point that the route.
We can solve the modal opened when the user refresh using the default.tsx.
Default, the default.tsx returns nulll.
But in this case, @icy cypress should render the opened modal in the default.tsx
Except this, the others are same as interception route.
Of course, @icy cypress have to use parallel route too.
I did like this but getting 404 error
/work-requests/[codename]/[id]
Just a sec, I will show you something.
default.tsx should go directly in @modal
Still showing 404 page
ah, I think that I was wrong on how children behaves. Could you rename work-requests/page.tsx to work-requests/default.tsx?
In this approach, it shows [codename]/[id]/page.tsx when refresh, and shows @modal/(.)/[id]/page.tsx when navigating. I don't want that
That doesn't work
It shows 404 page on /work-requests
ok. If you duplicate page.tsx to default.tsx; Also, I think we may be overcomplicating this. let me write something out.
I don't think I have to update /work-requests/page.tsx
There's no problem with that file
yeah, just copy that file
to work-requests/default.tsx
and if it works, you can refactor it's contents to share it between both. I'm not 100% sure tho
But it doesn't work
@modal/[codename]/[id]/page.tsx
Here's the modal content I want to show over /work-requests/page.tsx
You want work-requests/page.tsx to render for sub-routes as well, i.e. under this modal. I think the simplest way to do it is by moving it's contents to a layout file, as this is the purpose of the layout file. You could do so by doing something like this:
app/
├─ work-requests/
│ ├─ layout.tsx
│ ├─ page.tsx
│ ├─ [codename]/[id]/
│ │ ├─ page.tsx
with work-requests/layout.tsx containing your current work-requests/page.tsx contents and also rendering children, work-requests/page.tsx rendering nothing, but allowing the route to be accessed (i.e., the url example.com/work-requests renders work-requests/layout.tsx and work-requests/page.tsx), and the modal in [codename]/[id]/page.tsx.
lol, if I have another page under work-requests, then how? Use another sub-routes for that? 🤣
If work-requests has other routes which should NOT render the work requests page, for example work-requests/options or seomething of the sort, you could use a route group so that the layout will not render for those, and will only render for the other routes.
├─ work-requests/
│ ├─ (modal)
│ │ ├─ layout.tsx
│ │ ├─ page.tsx
│ │ ├─ [codename]/[id]/
│ │ │ ├─ page.tsx
│ ├─ (non-modal)
│ │ ├─ ... other subroutes
and (non-modal) shouldn't contain any matching routes for work-requests/; only for subroutes like work-requests/options etc.
Showing page content in layout.tsx is not the best practice. I hope there's another way
You could make work-requests/page.tsx a optional catch-all route, and then programatically show the modal. i.e. work-requests/[[...path]]/page.tsx
I jsut went and tested it myself, this is what worked for me.
can you please show what you updated?
localhost:3000/testshows the contents of/test/page.tsxand/test/@modal/default.tsxlocalhost:3000/test/modalshows the contents of/test/modal/page.tsxand/test/@modal/modal/page.tsx
I modified it to use a common component for both /test/page.tsx and /test/modal/page.tsx because that's what you want to do. I'll upload a gist and share it
the files are commented at the top where they go
So @acoustic knot, is it working in your case?
yes.
This question has been marked as answered! If you have any other questions, feel free to create another post
[Click here](#1315704038318411896 message)
I followed that @acoustic knot
Here's one more way to do it. This would be if you want a common backdrop page for the modal, and potentially you have multiple modals. I've attached screenshots showing the behavior
@acoustic knot, please check this code.
Using this way, we can implement the purpose also, but in this case, we can use the advantages of interception route such as route back, and show modal and full screen modal when the user refresh.
I think your implementation is fine, but not what Prince asked for. Prince explicitly wants the behavior to be the SAME, regardless of whether the user gets to the modal from work-requests or directly navigates to it (i.e, on refresh). In the case of what Prince wants, intercept routes are not applicable, because the behavior needs to be the same, regardless of how the user reaches the route.