π Next.js Advanced Route Patterns
The Magic of Multiple Doors
Imagine your house has just one door. Everyone uses itβguests, delivery people, family. Now imagine if your house could have multiple doors that work at the same time, and some doors could magically intercept visitors before they reach certain rooms!
Thatβs exactly what Next.js Advanced Route Patterns do for your web app. Letβs explore this magical house together!
π Parallel Routes: Multiple Rooms, One View
What Are Parallel Routes?
Think of watching TV while checking your phone. Two things happening at the same time, in the same space.
Parallel Routes let you show multiple pages simultaneously in one layout. Itβs like having a split-screen on your TV!
Real-Life Example
Picture a dashboard:
- Left side: Your notifications
- Right side: Your analytics
- Both update independently!
app/
βββ layout.js
βββ @notifications/
β βββ page.js
βββ @analytics/
β βββ page.js
βββ page.js
Why Is This Amazing?
| Old Way | With Parallel Routes |
|---|---|
| Load everything together | Each section loads independently |
| One error breaks all | Errors stay in their box |
| Hard to manage state | Clean separation |
π° Parallel Routes Slots: Named Boxes
What Are Slots?
Slots are like labeled boxes in your closet. Each box has a name starting with @.
@notifications β This is a slot!
@analytics β Another slot!
@sidebar β One more!
How Slots Work
graph TD A[Layout.js] --> B[@notifications] A --> C[@analytics] A --> D[Main Content] B --> E[Notifications Page] C --> F[Analytics Page]
Using Slots in Layout
// app/dashboard/layout.js
export default function Layout({
children,
notifications,
analytics,
}) {
return (
<div className="dashboard">
<main>{children}</main>
<aside>{notifications}</aside>
<section>{analytics}</section>
</div>
);
}
The Magic: Each slot is passed as a prop to your layout!
π default.js: The Backup Plan
Why Do We Need default.js?
Imagine youβre on a page, and one slot doesnβt have content for that route. What happens?
Without default.js: π₯ Error! With default.js: β¨ Shows fallback content!
The Problem It Solves
app/dashboard/
βββ layout.js
βββ @notifications/
β βββ page.js β Shows at /dashboard
β βββ archive/
β βββ page.js β Shows at /dashboard/archive
βββ @analytics/
β βββ page.js β Only at /dashboard
βββ page.js
When you go to /dashboard/archive:
@notifications/archive/page.jsβ Exists@analyticsfor/archive? β Missing!
The Solution
// app/dashboard/@analytics/default.js
export default function AnalyticsDefault() {
return (
<div>
<p>Select a view to see analytics</p>
</div>
);
}
Rule: Add default.js to every slot that might not match all routes!
π¦ Intercepting Routes: The Polite Doorman
What Are Intercepting Routes?
Youβre walking to your bedroom. A polite doorman stops you:
βWait! I can show you a preview right here. Want the full experience? Keep walking!β
Intercepting routes catch a navigation and show something elseβusually a modal or preview.
Real-World Example
Instagram-style photo viewing:
- Youβre on the feed
- Click a photo β Modal opens (intercepted!)
- Refresh page β Full photo page loads
Both use /photo/123, but the experience is different!
graph TD A[User clicks photo] --> B{From feed?} B -->|Yes| C[Show Modal] B -->|No/Refresh| D[Full Photo Page] C --> E[Same URL: /photo/123] D --> E
π Intercepting Route Conventions
The Special Symbols
Next.js uses special folder names to intercept:
| Symbol | Meaning | Example |
|---|---|---|
(.) |
Same level | (.)photo |
(..) |
One level up | (..)photo |
(..)(..) |
Two levels up | (..)(..)photo |
(...) |
From root | (...)photo |
How It Works
Think of it like file paths:
.means βright hereβ..means βgo up one folderβ
Folder Structure Example
app/
βββ feed/
β βββ page.js
β βββ (.)photo/
β βββ [id]/
β βββ page.js β Intercepts!
βββ photo/
βββ [id]/
βββ page.js β Full page
When in /feed and you click /photo/123:
β (.)photo/[id]/page.js catches it!
πΌοΈ Modal with Intercepting Routes
The Complete Recipe
Letβs build that Instagram-style modal!
Step 1: Create the Full Page
// app/photo/[id]/page.js
export default function PhotoPage({ params }) {
return (
<div className="full-photo">
<h1>Photo {params.id}</h1>
<img src={`/photos/${params.id}.jpg`} />
</div>
);
}
Step 2: Create the Interceptor
// app/feed/(.)photo/[id]/page.js
export default function PhotoModal({ params }) {
return (
<div className="modal-overlay">
<div className="modal">
<img src={`/photos/${params.id}.jpg`} />
</div>
</div>
);
}
Step 3: Add Modal Slot to Layout
// app/feed/layout.js
export default function FeedLayout({
children,
modal,
}) {
return (
<>
{children}
{modal}
</>
);
}
The Complete Structure
app/
βββ feed/
β βββ layout.js
β βββ page.js
β βββ @modal/
β βββ default.js β Empty when no modal
β βββ (.)photo/
β βββ [id]/
β βββ page.js β The modal!
βββ photo/
βββ [id]/
βββ page.js β Full page
The default.js for Modal
// app/feed/@modal/default.js
export default function ModalDefault() {
return null; // Nothing when modal is closed
}
π― Quick Reference
graph TD A[Advanced Patterns] --> B[Parallel Routes] A --> C[Intercepting Routes] B --> D[Slots @name] B --> E[default.js] C --> F[Conventions] C --> G[Modals] F --> H["#40;.#41; same level"] F --> I["#40;..#41; up one"] F --> J["#40;...#41; from root"]
π‘ When to Use What?
| Pattern | Use When |
|---|---|
| Parallel Routes | Dashboard with independent sections |
| Slots | Named regions that load separately |
| default.js | A slot might not match the current URL |
| Intercepting | Modals, previews, quick-views |
| Modal Pattern | Photo galleries, settings panels |
π You Did It!
You now understand:
- β How to show multiple routes at once
- β How to name and use slots
- β Why default.js saves the day
- β How to intercept navigation
- β How to build beautiful modals
Your Next.js apps just got superpowers! π¦ΈββοΈ
Remember: Advanced patterns arenβt scaryβtheyβre just tools that make complex UIs simple!