Next.js intercepting routes load a route from elsewhere in the app inside the current layout, while keeping the browser URL pointed at that route's real address. This is the mechanism behind a common pattern: clicking a photo in a feed opens it as a modal, but sharing that same URL loads the full photo page instead.
app/
feed/
page.tsx
(.)photo/
[id]/
page.tsxThe (.)photo folder intercepts the photo segment for navigations that start from the feed. Clicking through from the feed renders the intercepted version inside the feed's layout; loading the photo URL directly renders the normal, non-intercepted page instead. The dynamic id segment inside the intercepted folder works exactly like any other dynamic route, covered in dynamic routes in Next.js.
The dot conventions
The prefix tells Next.js how many segment levels up the real route sits, counted in route segments rather than file-system folders.
| Prefix | Matches |
|---|---|
(.) | Same segment level |
(..) | One segment level above |
(..)(..) | Two segment levels above |
(...) | From the root of the app directory |
A @slot folder from a parallel route does not count as a level, since it is not a route segment either. This is why a modal slot two folders deep on disk can still intercept a route that is only one segment away in the URL.
Interception only happens on soft navigation
Clicking a link that triggers a client-side transition is what activates the interception. A hard navigation, such as a full page reload or pasting the URL directly into the address bar, always renders the real, un-intercepted route. This is intentional: it is what keeps a modal shareable and reload-safe, since the link a visitor copies always resolves to a real, standalone page.
Building a modal with intercepting and parallel routes
An intercepting route alone has nowhere obvious to render, so building an actual modal pairs it with a parallel route slot. The slot supplies the layout position for the modal, and the intercepting folder inside that slot supplies the content shown during a soft navigation.
// app/@modal/(.)photo/[id]/page.tsx
export default function InterceptedPhoto() {
return <p>Modal photo view</p>;
}The parent layout renders this slot alongside the page's regular children, and a default.tsx file in the same slot returns null so nothing shows when no photo is being viewed. The full step-by-step slot setup is covered in parallel routes in Next.js.
Common mistake
Expecting the modal to survive a page refresh is a common point of confusion. Because interception depends on client-side navigation state, refreshing always falls back to the real route, which is the correct and expected behavior for a URL meant to be shareable rather than a bug to work around.
Rune AI
Key Insights
- A folder prefixed with (.) intercepts a route at the same segment level.
- (..) intercepts one level above, and (...) intercepts from the root.
- Interception only happens on soft, client-side navigation.
- A hard navigation or refresh renders the real route instead of the intercepted view.
- Intercepting routes need a parallel route slot to actually render as a modal.
Frequently Asked Questions
Do intercepting routes work without parallel routes?
Why does the modal disappear on refresh and show a full page instead?
Are the dot conventions based on folders or on URL segments?
Conclusion
An intercepting route loads another part of the app inside the current layout while keeping the URL pointed at that route's real address. Combined with a parallel route slot, this is what makes a shareable, refresh-safe modal possible.
More in this topic
`generateMetadata` Explained with Real Examples
What generateMetadata does, when it runs, and how to use it for real routes: awaited params, deduplicated data fetching, extending parent metadata, and returning a 404 from metadata.
Canonical URLs in Next.js: `metadataBase`, `alternates.canonical`, and Dynamic Pages
How canonical URLs work in the Next.js App Router: setting metadataBase once, writing alternates.canonical per route, handling dynamic segments, and what happens when the base URL is missing.
Open Graph and Twitter Card Metadata in Next.js
How to write Open Graph and Twitter card metadata in the Next.js App Router: the openGraph and twitter fields, automatic card defaults, article tags, and image merge rules.