Maximizing Routing Flexibility with Next.js Parallel and Intercepting Routes
Introduction:
Next.js, a powerful React framework, offers two essential features - Parallel Routes and Intercepting Routes - that enable developers to create highly dynamic and seamless user experiences in their applications. In this blog post, we will explore both Parallel Routes and Intercepting Routes, highlighting their functionalities, use cases, and how they can be combined to enhance application routing.
What are Parallel Routes?
Parallel Routes in Next.js allow the rendering of multiple pages within a shared layout. Rather than navigating to a completely separate page, Parallel Routes enable the simultaneous rendering of different pages based on certain conditions such as user roles or tab navigation. By leveraging named slots, defined using the @folder
convention, multiple pages can be seamlessly integrated into a single layout, enhancing user experience and reducing code duplication.
How to Use Parallel Routes:
To utilize Parallel Routes in Next.js, you must define named slots for the desired pages within your application's folder structure. These slots are then passed as props to a shared parent layout component. For example, consider a social networking application where two pages, feed and notifications, must be rendered within a common layout. You can define Parallel Routes using the following structure:
-app
- @feed
- page.tsx
- @notifications
- page.tsx
- layout.tsx
- page.tsx
The layout component in app/layout.js
will accept the @feed
and @notifications
slots as props and render them alongside the children prop. Here's an example of the layout component:
export default function Layout({
children,
feed,
notifications,
}) {
return (
<>
{children}
{feed}
{notifications}
</>
)
}
It's important to note that slots do not affect the URL structure and are not considered route segments. This means the URL would be /mypage/@feed/views
for a route like /mypage/views
since @feed
is a slot.
Also, to prevent the application from rendering nothing or throwing an error, we could use the default.tsx
file:
-app
- @feed
- page.tsx
- @notifications
- page.tsx
- layout.tsx
- page.tsx
- default.tsx
In this example, the default.tsx
file specifies the default content (or fallback) to render when none of the named slots match the current route. It acts as a catch-all for routes without a corresponding slot.
Some Use Cases:
Conditional Routes: Parallel Routes can conditionally render routes based on certain conditions, such as user roles. For example, you can render a different dashboard page for admins and users. This can be achieved by creating a layout component specific to the dashboard and checking the user role to determine which slot to render.
Tab Groups: You can utilize Parallel Routes to create tabbed navigation within a section. This is especially useful for analytics or multi-page views. Adding a layout inside a slot allows users to navigate between different pages within that slot independently.
Loading and Error UI: Parallel Routes can be independently streamed, allowing you to define custom error and loading states for each route. This enables better control over the user experience by providing distinct feedback for different app sections.
Modals: Parallel Routes can be combined with Intercepting Routes to create modals with shareable URLs, preserved context on refresh, and customized navigation behavior. By intercepting certain routes and rendering them within a modal component, you can create a seamless modal experience.
Understanding Intercepting Routes:
Intercepting Routes in Next.js allows you to load content from another route within the current layout without changing the URL or refreshing the page.
Using the (..) Convention:
Intercepting routes are defined using the (..)
convention, which is similar to the relative path convention ../
but for route segments. The convention allows for matching segments on the same level (.)
, one level above (..)
, two levels above (..)(..)
, or from the root app directory (...)
. For example, to intercept the photo segment from within the feed segment, you can create a (..)photo
directory.
Integrating Intercepting Routes with Parallel Routes - Modals:
One powerful use case for Intercepting Routes is creating modals, which can be combined with Parallel Routes to solve common challenges such as making the modal content shareable through a URL, preserving context on page refresh, and handling backward and forward navigation.
Let's make an example:
// Layout Component for gallery
export default function Layout({ children, modal }) {
return (
<>
{children}
{modal}
</>
)
}
// Photo Component inside the (..)photo folder
export default function Photo({ id }) {
return <Modal><PhotoDetail id={id} /></Modal>
}
// Gallery Page
export default function Gallery() {
return allPhotos.map((photo) =>
<Link href=`/photo/${photo.id}`>
<Photo>
<Link>
)
}
// Photo page inside the photo folder
export default function Photo({ id }) {
return <PhotoDetail id={id} />
}
Our folder structure will be:
In this example, when a user clicks on a photo within the /gallery
page, the route /photo/:photoId
will be intercepted and rendered within the (..)photo
directory, overlaying the gallery content. This means that the photo route is only one segment level higher despite being two file-system levels higher.
In the example above, the path to the photo segment can use the (..)
matcher since @modal
is a slot and not a segment.
Common Use Cases - Beyond Modals:
Intercepting Routes can also be utilized in other scenarios. Some examples include opening a login modal in a top navbar while having a dedicated /login
page, or opening a shopping cart in a side modal for better accessibility or creating wizards or multi-step forms within a single page. The possibilities are endless.
Conclusion
Next.js Parallel and Intercepting Routes offer powerful methods for enhancing the routing capabilities of your applications. With Parallel Routes, multiple pages can be seamlessly integrated within a shared layout, simplifying navigation and enhancing user experience. By incorporating Intercepting Routes, you can create dynamic overlays like modals, enabling content from different routes to be displayed within the current layout. By leveraging these features, you can unlock exciting possibilities and take your Next.js applications to new heights of user engagement.