How to Use Intercepting Routes in Next.js for Flexible Navigation
In Next.js,
intercepting routes let you capture and render nested routes inside a parent route without changing the URL structure. You create them by using parentheses in folder names like (modal) to intercept navigation and show UI such as modals or sidebars while keeping the main route active.Syntax
Intercepting routes use special folder names with parentheses to capture nested routes without changing the main URL path. The syntax is:
(segment): Defines an intercepting route segment.- Use inside the
app/directory to group routes. - Combine with
layout.tsxorpage.tsxfiles to control rendering.
This lets you show UI like modals or sidebars on top of the current page.
typescript
app/(modal)/page.tsx // This folder intercepts routes to show a modal UI app/page.tsx // Main page that stays visible under the modal
Example
This example shows a main page with a button that opens a modal using an intercepting route. The modal appears without changing the main URL path.
typescript
/* app/page.tsx */ 'use client'; import Link from 'next/link'; export default function HomePage() { return ( <main> <h1>Home Page</h1> <Link href="/(modal)" replace> <button>Open Modal</button> </Link> </main> ); } /* app/(modal)/page.tsx */ 'use client'; import Link from 'next/link'; export default function Modal() { return ( <div style={{ position: 'fixed', top: 0, left: 0, width: '100vw', height: '100vh', backgroundColor: 'rgba(0,0,0,0.5)', display: 'flex', justifyContent: 'center', alignItems: 'center', color: 'white', fontSize: '2rem' }}> <div style={{ background: 'black', padding: '2rem', borderRadius: '8px' }}> <p>This is a modal!</p> <Link href="/" replace> <button>Close Modal</button> </Link> </div> </div> ); }
Output
Home Page with a button labeled 'Open Modal'. Clicking it overlays a modal with text 'This is a modal!' and a 'Close Modal' button that returns to the Home Page.
Common Pitfalls
- Not using parentheses in folder names means the route is not intercepting but normal nested routing.
- Forgetting to use
replaceinLinkcan cause unexpected browser history behavior. - Not styling the modal overlay properly can block interaction with the main page.
- Using intercepting routes outside the
app/directory is not supported.
typescript
/* Wrong: folder named 'modal' instead of '(modal)' */ app/modal/page.tsx // This creates a normal nested route, not an intercepting route /* Right: folder named '(modal)' */ app/(modal)/page.tsx // This intercepts the route and overlays UI
Quick Reference
| Concept | Description | Example |
|---|---|---|
| Intercepting Route Folder | Use parentheses to create intercepting segments | (modal) |
| Link with replace | Use replace to avoid extra history entries | <Link href='/(modal)' replace> |
| Overlay UI | Render UI like modals without changing main route | Modal inside (modal)/page.tsx |
| Location | Only inside app/ directory | Place intercepting folders under app/ |
Key Takeaways
Use parentheses in folder names inside the app directory to create intercepting routes.
Intercepting routes let you overlay UI like modals without changing the main URL path.
Always use the replace prop on Link to manage browser history correctly with intercepting routes.
Style overlays carefully to keep the main page visible and interactive underneath.
Intercepting routes only work in the Next.js app router, not in pages router.