Intercepting Routes

Show a Different UI When Navigating From an In-App Link

Intercepting Routes

An (..)folder intercepts a route only when navigated to from another route — the classic pattern for modal overlays that keep the underlying page visible.

4 min read Level 3/5 #nextjs#intercepting-routes
What you'll learn
  • Use `(.)`, `(..)`, and `(...)` interception levels
  • Build a modal that intercepts an in-app navigation
  • Allow a real page on a direct visit

Intercepting routes solve a problem that has been awkward in React forever: when a user clicks an item, show a modal — but if they share or refresh that URL, show a full page. Next.js handles both with one route tree.

The Interception Markers

The marker is a parenthesized dot prefix in front of a folder name:

  • (.)folder — intercept a sibling
  • (..)folder — intercept one level up
  • (..)(..)folder — intercept two levels up
  • (...)folder — intercept from the app root

You read it like .. in a path, but with parentheses so Next.js does not treat it as a folder name.

A list of photos, each clickable. Clicking should open a modal. Refreshing should show the full photo page.

app/photos/
  page.tsx                   # the list
  [id]/page.tsx              # full page on direct hit
  (..)photos/[id]/page.tsx   # modal when navigated from /photos

The intercepted route lives alongside a parallel modal slot in the parent layout.

// app/layout.tsx
export default function RootLayout({
  children,
  modal,
}: {
  children: React.ReactNode;
  modal: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        {modal}
      </body>
    </html>
  );
}
// app/@modal/(..)photos/[id]/page.tsx
import { Modal } from '@/components/modal';

export default async function PhotoModal({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  return (
    <Modal>
      <img src={`/photos/${id}.jpg`} alt="" />
    </Modal>
  );
}

Why Two Routes for One URL

  • Soft navigation from /photos to /photos/123 hits the intercepted route → modal
  • A direct visit or refresh of /photos/123 hits the regular [id]/page.tsx → full page

The exact same URL, two different UIs, chosen by navigation context.

That wraps the structural routing primitives. The next lesson moves on to the client-side navigation API.

Link & Client-Side Navigation →