Intercepting Routes

Modals With Real URLs

On Instagram, clicking a photo in the feed opens it in a modal, but the URL changes to /p/abc. Reloading shows the full photo page. Next.js does this with intercepting routes + a parallel @modal slot.

ConventionIntercepts
(.)folderSame level
(..)folderOne level up
(..)(..)folderTwo levels up
(...)folderFrom the app root

Note: The (..) refers to route segments, not file-system folders, so slots like @modal and groups do not count.

Quick View for Products

app/products/
├── layout.tsx                    renders {children} and {modal}
├── page.tsx                      product grid
├── [id]/page.tsx                 full product page (direct visit / reload)
└── @modal/
    ├── default.tsx               return null
    └── (.)[id]/page.tsx          quick-view modal (client navigation from the grid)
// app/products/@modal/(.)[id]/page.tsx
import Modal from '@/components/Modal'; // 'use client', calls router.back() on close
import { getProduct } from '@/lib/data/products';

export default async function QuickView({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const product = await getProduct(Number(id));
  return (
    <Modal>
      <h2>{product?.name}</h2>
      <p>₹{product?.price}</p>
    </Modal>
  );
}
// app/products/layout.tsx
export default function Layout({ children, modal }: { children: React.ReactNode; modal: React.ReactNode }) {
  return (
    <>
      {children}
      {modal}
    </>
  );
}

Behaviour

ActionResult
Click a product in the gridModal opens, URL is /products/42
Press BackModal closes, grid is still there
Reload or share the URLFull product page renders