- Next.js
- Advanced Routing & Interception
- Intercepting Routes: Feed-to-Modal Workflows
Intercepting Routes: Feed-to-Modal Workflows
Intercepting Routes allow a route to intercept another route within the current layout during client-side navigation, rendering it as an overlay modal while keeping the underlying feed visible. On a hard page refresh or direct URL access, Next.js renders the full standalone page instead. Intercepting routes use relative segment markers: (.) same level, (..) one level up, (..)(..) two levels up, and (...) from the app root.
Learning Objectives
Understand the four interception segment conventions: (.), (..), (..)(..), and (...).
Combine Parallel Routes (@modal) with Intercepting Routes to implement Instagram/Pinterest style photo modals.
Maintain shareable, bookmarkable URLs for modal dialogs.
Handle modal dismissal via router.back() with seamless scroll restoration.
Prerequisites & Background Knowledge
Why Interviewers Care
A signature Next.js App Router pattern frequently tested in UI system design interviews (e.g. "Design the Instagram photo feed with shareable modal").
The Challenge
Explain how Intercepting Routes enable modal overlays during client navigation while preserving direct URL shareability. Implement a feed-to-modal photo viewer using (@modal)(..)photo/[id].
Code Architecture & Implementation
1// app/feed/@modal/(..)photo/[id]/page.tsx2'use client';34import { useRouter } from 'next/navigation';5import { use } from 'react';67export default function PhotoModal({ params }: { params: Promise<{ id: string }> }) {8 const router = useRouter();9 const { id } = use(params);1011 return (12 <div className="fixed inset-0 bg-black/75 z-50 flex items-center justify-center p-4">13 <div className="bg-white rounded-lg p-6 max-w-xl w-full relative">14 {/* Dismiss modal by stepping back in history */}15 <button16 onClick={() => router.back()}17 className="absolute top-2 right-2 text-gray-500 hover:text-black"18 >19 ✕ Close20 </button>21 <h2 className="text-xl font-bold mb-4">Photo Preview #{id}</h2>22 <img23 src={`https://picsum.photos/seed/${id}/600/400`}24 alt="Modal Preview"25 className="rounded w-full"26 />27 <p className="mt-2 text-sm text-gray-600">28 Shareable URL: /photo/{id} (Try refreshing the page!)29 </p>30 </div>31 </div>32 );33}
Architectural Explanation
When a user clicks a photo link from /feed, Next.js detects the intercepting segment (..)photo/[id] in the active @modal slot. Instead of navigating away from the feed, it renders the modal inside the @modal slot while updating the browser address bar to /photo/123. The user maintains their feed scroll position. If the user copies that URL and opens it in an incognito window, Next.js does NOT intercept it because there is no prior feed layout in history; instead, it renders the standalone /photo/[id]/page.tsx full-screen page.
Common Mistakes & Anti-Patterns
Using filesystem path depth instead of route segment depth when calculating `(..)` markers.
Forgetting to implement `default.tsx` returning `null` in the `@modal` slot, leaving stale modal UI on subsequent routes.
Closing the modal with `router.push("/feed")` instead of `router.back()`, which pollutes the browser navigation history.
Interview Follow-Up Traps
The interviewer asks: "What happens if a user navigates to an intercepted route from outside the domain?" Interception only occurs on client-side SPA navigation. Direct external arrivals always render the standalone page.
Frequently Asked Questions
How do you handle pressing the Escape key to close the modal?
Attach a window keydown event listener inside the modal component calling `router.back()`.
Can you have nested modals using intercepting routes?
Yes, by combining multiple slots or stacking intercepting route segments.
