|$ curl https://forge-ai.dev/api/markdown?path=docs/nextjs/intercepting-routes
$cat docs/next.js-—-intercepting-routes.md
updated Last week·14 min read·published

Next.js — Intercepting Routes

Next.jsAdvanced🎯Free Tools
Introduction

Intercepting routes allow you to show a route layout while the browser URL remains on a different route. This enables patterns like showing a modal over the current page without navigating away — the user sees the content inline but the URL can be shared and bookmarked to show the full page.

Interception Syntax
interception-syntax
TEXT
1// The (..) syntax intercepts one level up
2// The (...) syntax intercepts two levels up
3// The (.) syntax intercepts the same level
4
5// Folder structure:
6// app/
7// feed/
8// page.tsx — /feed (image grid)
9// (..)photo/
10// [id]/
11// page.tsx — intercepts /photo/[id] when navigating from /feed
12// photo/
13// [id]/
14// page.tsx — /photo/[id] (full page view)
15
16// (..) — intercepts one segment above
17// app/feed/(..)photo/[id]/page.tsx intercepts /photo/[id]
18// when the user is on /feed
19
20// (...) — intercepts multiple segments
21// app/(...)photo/[id]/page.tsx intercepts /photo/[id]
22// from anywhere in the app
23
24// (.) — intercepts same level
25// app/feed/(.)photo/[id]/page.tsx intercepts /feed/photo/[id]

info

Use (..) for parent-level interception. The number of dots determines how many path segments to go up. (.) intercepts at the same level.
Login Intercepting Pattern
login-pattern.tsx
TSX
1// Show login as modal on protected pages, full page when accessed directly
2
3// app/login/page.tsx — Full login page (direct navigation)
4export default function LoginPage() {
5 return (
6 <div className="min-h-screen flex items-center justify-center">
7 <div className="w-96 p-8 bg-gray-900 rounded-lg">
8 <h1 className="text-xl font-bold mb-4">Sign In</h1>
9 <LoginForm />
10 </div>
11 </div>
12 );
13}
14
15// app/(.)login/page.tsx — Intercepted modal login
16export default function LoginModal() {
17 return (
18 <div className="fixed inset-0 z-50 flex items-center justify-center">
19 <div className="absolute inset-0 bg-black/80" />
20 <div className="relative z-10 w-96 p-8 bg-gray-900 rounded-lg">
21 <h1 className="text-xl font-bold mb-4">Sign In</h1>
22 <LoginForm />
23 </div>
24 </div>
25 );
26}
27
28// app/dashboard/page.tsx — Protected page links to login
29import Link from "next/link";
30
31export default function Dashboard() {
32 return (
33 <div>
34 <h1>Dashboard</h1>
35 <p>Please sign in to continue.</p>
36 {/* Clicking this shows login as modal (intercepted) */}
37 {/* URL changes to /login but dashboard stays visible */}
38 <Link href="/login">Sign In</Link>
39 </div>
40 );
41}

best practice

Intercepting routes are ideal for modals over existing content. The URL is shareable and works on page refresh (shows the full page version). This is a significant improvement over JavaScript-only modal solutions.
Parallel Routes Integration
parallel-integration.tsx
TSX
1// Combining intercepting routes with parallel routes for advanced layouts
2
3// app/layout.tsx
4export default function Layout({
5 children,
6 modal,
7}: {
8 children: React.ReactNode;
9 modal: React.ReactNode;
10}) {
11 return (
12 <div>
13 {children}
14 {modal}
15 </div>
16 );
17}
18
19// app/@modal/default.tsx — empty default so it doesn't render when not intercepted
20export default function Default() {
21 return null;
22}
23
24// app/@modal/(.)photo/[id]/page.tsx — intercepted modal
25export default async function PhotoModal({
26 params,
27}: {
28 params: Promise<{ id: string }>;
29}) {
30 const { id } = await params;
31 return (
32 <div className="fixed inset-0 z-50 flex items-center justify-center">
33 <div className="absolute inset-0 bg-black/80" />
34 <div className="relative z-10">
35 <img src={"/api/photo/" + id} alt="Photo" />
36 </div>
37 </div>
38 );
39}
40
41// The @modal slot renders null by default (default.tsx)
42// When navigating to /photo/[id] from a page that has interception,
43// the modal slot renders the intercepted content instead
$Blueprint — Engineering Documentation·Section ID: NEXT-INTR·Revision: 1.0