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 Parallel Routes highlighting their functionalities, use cases, and how it can be combined to enhance application routing.
What are parallel routes?
Parallel routes are most useful when rendering complex, dynamic sections of an application, such as in a dashboard with multiple independent sections or a modal.
The image below is an illustration of a dashboard page from the Next documentation that demonstrates the intricacies of parallel routes:
How to use parallel routes
Parallel routes in Next.js are defined using a feature known as slots. Slots help structure our content in a modular fashion. To define a slot, we use the @folder naming convention. Each slot is then passed as a prop to its corresponding layout.tsx file .
In the context of our dashboard example, we would define two distinct slots within the app folder: @team for the team section, @analytics for the analytics section.
For simplicity, we will include content within the slots as follows:
The layout component in app/layout.js will accept the @team and @analytics slots as props and render them alongside the children prop. Here's an example of the layout component:
It is important to note that slots are not route segments and do not affect the URL structure.
Why Use Parallel Routes
A clear benefit of parallel routes is their ability to split a single layout into various slots, making the code more manageable. This is particularly advantageous when different teams work on various sections of the page.
However, the true benefit of parallel routes lies in their capacity for independent route handling and sub-navigation. Let’s take a closer look at these benefits.
Independent route handling
Each parallel route is streamed independently to the layout, allowing for individual loading and error states, completely isolated from other parts of the layout.
For instance, if a section like analytics takes longer to load than other dashboard sections, a loading indicator can be displayed for that section alone, while the remaining sections remain fully interactive.
We can achieve this by defining loading.tsx and error.tsx files within each slot, as demonstrated in the illustration below:
For instance, if the analytics data takes longer to load, you can display a loading spinner specifically for that section, while other parts of the dashboard remain interactive. Similarly, if there's an error in the fetching team, you can show an error message in that specific section without affecting the rest of the dashboard. This level of detail in handling states not only improves the user experience but also simplifies debugging and maintenance.
Sub-navigation in routes
The independent attribute of a slot extends beyond the loading and error state. Each route operates as a standalone entity, complete with its own state management and navigation, thus making each section of the user interface (in this context, the dashboard) operate as a standalone application.
This implies that we can create sub-folders that are associated with the @folder/sub-folder file path within the slots and navigate back and forth without altering the state or rendition of the other sections on the dashboard.
For example, if we wish to implement sub-navigation within the @analytics slot, we can create a subfolder as follows:
This setup allows seamless navigation between the analytics and notification views, without impacting other sections of the home page.
However, it's important to consider how this affects other parts of the home page, particularly the behavior of the children, team slots since they don't have an notification folder defined.
Handling unmatched routes
By default, the content rendered within a slot matches the current URL. In our folder, we have two slots: team, analytics.
All these slots render their defined content when visiting localhost:3000/. However, when navigating to localhost:3000/notification, only the analytics slot has a matching route. The other slot - team - becomes unmatched.
When dealing with an unmatched slot, the content rendered by Next.js depends on the routing approach:
Let’s take a closer look at including the default.tsx file in our dashboard route.
default.tsx
The default.tsx file in Next.js serves as a fallback to render content when the framework cannot retrieve a slot's active state from the current URL. You have complete freedom to define the UI for unmatched routes: you can either mirror the content found in page.tsx or craft an entirely custom view.
Now, when we engage in a hard navigation to the /notification route, the page will load correctly and render the default view for unmatched routes.
Conclusion
Next.js Parallel offers 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.