Next.js - Intercepting Routes



Intercepting Routes

The intercepting routes is Next.js 13 feature, that allows to load a route from another part of your application within the current layout. This is particularly useful when you want to create a overlay experience, without fully navigating away from the current page.

Example Use Case

Imagine, you need to make a photo gallery website in which, clicking a thumbnail shows a modal with the full photo while keeping the gallery visible in the background. This routes can be defined by,

app/
  gallery/
    page.js          // Gallery with thumbnails
    [id]/
      page.js        // Full photo page
    (.)[id]/
      page.js        // Modal interceptor for photo

How Intercepting Routes Work

The working principle of intercepting routes can be explained as follows:

  • Route Grouping: The intercepting routes are grouped together in a folder. This will tell Next.js that these routes should behave differently. The parent layout stays rendered even when you navigate to an intercepting route.
  • Overlay Experience: When you navigate to an intercepting route, the parent layout will be rendered with a transparent background. The new UI will be overlaid on top of the parent layout.
  • Route naming convention: The intercepting routes use a special file naming convention with parentheses and dots,
    • (.) - Intercept same segment level
    • (..) - Intercept one segment level above
    • (..)(..) - Intercept two segment levels above
    • (...) - Intercept from the root app directory

Implementation and Example

To implement intercepting routes, First you need to create a base route. This route will be rendered with a transparent background. In the code below, we defined base route for the gallery website mentioned above.

// app/gallery/page.js

export default function Gallery() {
  return (
    <div>
      <h1>Photo Gallery</h1>
      <div className="grid">
        {photos.map(photo => (
            <Link key={photo.id} href={`/gallery/${photo.id}`}>
                    <img src={photo.thumbnail} alt={photo.title} />
            </Link>
        ))}
      </div>
    </div>
  );
}

// app/gallery/[id]/page.js

export default function PhotoPage({ params }) {
  const photo = getPhoto(params.id);
  return (
    <div className="full-page">
        <h1>{photo.title}</h1>
        <img src={photo.fullSize} alt={photo.title} />
        <p>{photo.description}</p>
    </div>
  );
}

Output

This will create an experience where clicking a photo in the gallery shows it in a modal, but users can also share direct links to the full photo page. When each route activates,

  • Direct navigation to /gallery/123 app/gallery/[id]/page.js
  • Navigation from /gallery to /gallery/123 app/gallery/(.)[id]/page.js
Advertisements