Modern routing is no longer about just switching pages.
We expect real-app behavior:
- Open a detail view in a modal
- Keep the list in the background
- Preserve scroll position
- Go back with browser’s back button
- Direct URL loads the full page (SEO-friendly)
- Open modals from anywhere in the app
If you're coming from React Router, this is easy.
But when you try to do the same in Next.js App Router, things suddenly feel… complicated.
Why does Next.js need Parallel Routes and Intercepting Routes, while React Router just uses <Outlet />?
Let’s get to the core reason — and once you see it, everything else makes sense.
🎯 The Real Reason: File-Based Routing Has Limitations That Component-Based Routers Don’t
React Router is powered by a declarative routing tree:
You explicitly write parent → child → nested child routes.
<Route path="posts" element={<PostsPage />}>
<Route path=":id" element={<PostModal />} />
</Route>
This means:
- Navigating to
/posts/:idnaturally renders both parent + child. - Parent stay mounted.
- Child can be rendered as modal.
- Scroll position in parent is preserved.
- Nested flows are automatic.
💡 Modals, sidebars, and split views feel “free” in React Router.
They come directly from the route tree.
❌ But Next.js Doesn’t Have a Declarative Route Tree
Instead, it has file-based routing.
app/posts/page.tsx → /posts
app/posts/[id]/page.tsx → /posts/:id
These two files are siblings — not parent and child.
Meaning:
❌ Navigating to /posts/10 DOES NOT render /posts/page.tsx.
❌ Your list page does NOT stay in the background.
❌ You can't overlay a modal by default.
❌ You can’t preserve scroll or state automatically.
❌ No <Outlet /> equivalent inside page files.
This is the root of all the pain.
Next.js needed new primitives because its core routing rules do not naturally support nested UI behavior.
So the framework added:
⭐ Parallel Routes
⭐ Intercepting Routes
Two powerful features that patch the gap created by file-based routing.
Let’s break down why.
🟦 1. Why Parallel Routes Are Needed
Parallel routes allow multiple route segments to render at the same time.
React Router can do this because:
- The parent route stays mounted
- The child route can appear inside it
In Next.js file routing:
-
/postsand/posts/[id]do not mount together - The router replaces the whole screen
- Background UI is destroyed
So Next.js needed a way to keep multiple routes alive.
Parallel routes add multiple slots:
children → main content
@modal → modal content
@sidebar → sidebar content
This gives you:
- Persistent background routes
- Preserved state + scroll
- Multiple independent layouts
- Multiple simultaneous route branches (previously impossible in file routing)
🔥 This is something <Outlet/> gives React Router for free, but Next.js must explicitly implement.
🟥 2. Why Intercepting Routes Are Needed
Parallel routes alone don’t solve the other big challenge:
“How do we decide whether
/posts/10should show a modal or a full-page?”
React Router solves this naturally:
- Route context is inherited
- Child routes render within parent
- Direct URL loads child alone = full page
- Navigation from parent renders child in Outlet = modal style
Next.js has no nested route relationships between files, so it cannot infer this.
Intercepting routes tell Next.js:
- When user navigates from within
/posts→ show modal version - When user opens
/posts/10directly → show full-page version
This behavior is impossible in pure file-based routing without explicit routing rules.
Intercepting routes override the route lookup to show different UI depending on navigation context — just like Instagram, Twitter, YouTube modals.
🧩 Final Mental Model
⭐ React Router
Component-based routing
- Nested routes → natural parent/child rendering
- Modals, keeps background alive → automatic
- One routing tree handles everything
⭐ Next.js
File-based routing
- Sibling pages don’t share parent/child behavior
- No nested UI by default
- Background page disappears on navigation
- Needs additional routing primitives
So Next.js introduces:
| Feature | Purpose |
|---|---|
| Parallel Routes | Render multiple routes together (background + modal) |
| Intercepting Routes | Choose modal vs full-page based on user navigation |
Together, they recreate the nested UI abilities React Router already has — but in a file-based routing architecture.
Top comments (0)