typescriptadvanced

Intercepting Routes Modal

Show content in a modal on soft navigation while preserving the full page on hard navigation.

typescript
// app/@modal/(.)photo/[id]/page.tsx
// The (.) prefix intercepts /photo/[id] at the same level

import { Modal } from '@/components/Modal';

export default function PhotoModal({ params }: { params: { id: string } }) {
  return (
    <Modal>
      <img
        src={`/photos/${params.id}.jpg`}
        alt={`Photo ${params.id}`}
        className="max-h-[80vh] rounded-xl"
      />
    </Modal>
  );
}

// app/@modal/default.tsx
export default function Default() {
  return null; // No modal by default
}

// app/layout.tsx
export default function Layout({
  children,
  modal,
}: {
  children: React.ReactNode;
  modal: React.ReactNode;
}) {
  return (
    <>
      {children}
      {modal}
    </>
  );
}

Use Cases

  • Photo gallery modals
  • Login interceptors
  • Quick preview overlays

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.