DEV Community

Cover image for Next.Js 13 Parallel Routes: A Comprehensive Guide
Leandro Nuñez for Digital Pollution

Posted on

Next.Js 13 Parallel Routes: A Comprehensive Guide

1. Introduction

Hello there!
Welcome to this comprehensive guide on parallel routes in Next.js.

As the digital landscape evolves, so do the intricacies of web development. Modern web applications require not just robust, but also versatile routing mechanisms to enhance user experience and accommodate intricate design structures.

This article is meticulously crafted to understand the powerful feature introduced in Next.js 13.3 - Parallel Routes. The objective is twofold: firstly, to provide a clear understanding of the significance of parallel routes and their practical applications, and secondly, to offer hands-on insights into implementing them efficiently in your Next.js projects.

Let's start this journey to explore the transformative potential of parallel routes and how they're redefining the boundaries of web application design.


2. The World Before Parallel Routes

Before the inception of parallel routes, web developers were limited in how they could structure and display content dynamically on a single view. Traditional routing mechanisms were fairly linear: one URL, one view.

For instance, consider a typical dashboard design:

// pages/dashboard/user.js
function User() {
  return <div>User Dashboard</div>;
}

// pages/dashboard/team.js
function Team() {
  return <div>Team Dashboard</div>;
}
Enter fullscreen mode Exit fullscreen mode

Navigating to /dashboard/user would render the User Dashboard, while /dashboard/team would show the Team Dashboard. The two were mutually exclusive. To view a different segment, a user would typically have to navigate away from their current view entirely.

This posed challenges, especially when developers wanted to display multiple segments of a website simultaneously or conditionally. The traditional routing approach lacked flexibility, making it hard to create complex, interactive layouts like side-by-side dashboards or modals without resorting to intricate state management or workarounds.

Thankfully, with the evolution of frameworks like Next.js and the introduction of parallel routes, this landscape has been drastically altered, ushering in a new era of dynamic and adaptive web design.


3. Understanding Parallel Routes

Parallel Routes are groundbreaking features introduced in Next.js 13.3, significantly altering how developers approach routing and the presentation of content on the web.

3.1 Introduction to Parallel Routes:

Next.js 13.3 brings forth a fresh dynamic convention, enabling the implementation of more advanced routing cases. As stated in the documentation,

"Parallel Routes allow you to show more than one page in the same view, like with complex dashboards or modals. With Parallel Routes, you can simultaneously render one or more pages in the same view that can be navigated independently."

In simpler terms, different components or sections of your app can load simultaneously, giving a sense of fluidity and responsiveness, especially if certain components take longer due to fetching data or rendering.

3.2 Use Cases: Dashboards, Modals, and More:

The structure of modern web applications often demands advanced layouts that combine several views or require contextual pop-ups without losing the underlying content.

Take the example from the documentation:

  dashboard
  |__ @user
  |____ page.js
  |__ @team
  |____ page.js
  |__layout.js
  |__ page.js
Enter fullscreen mode Exit fullscreen mode

This layout demonstrates how Parallel Routes can be employed to simultaneously display user and team dashboards on the same view using named "slots", a feature native to this new routing approach.

3.3 Benefits: Multiple Pages View, Conditional Rendering, Independent Navigation:

The advantages of Parallel Routes are manifold. As highlighted, they permit

"simultaneous rendering of one or more pages in the same view that can be navigated independently".

Additionally, they can be leveraged for conditional rendering of pages, thereby offering an unprecedented level of flexibility and dynamism to web applications.

In essence, with the advent of Parallel Routes, web developers are now better equipped to construct intricate, dynamic, and user-friendly web interfaces, tailor-made for the evolving needs of the modern web.


4. How Parallel Routes Work

Getting deeper into Parallel Routes shows how smartly Next.js 13.3 is built. Let’s go through the details step by step.

4.1 Introducing "Slots" and the @folder Convention:

The concept of "slots" lies at the heart of Parallel Routes. Think of slots as designated areas that can display different pages or parts of your website.

The @folder convention is the method used to set up these slots, as evidenced by the documentation's note: "Parallel Routes use these named 'slots', defined using the @folder method."

  • Code Explanation:

    • Folder Structure for Parallel Routes: Consider this example:
    dashboard
    |__ @user
    │____ page.js
    |__ @team
    |____ page.js
    |__ layout.js
    |__ utilities.js
    |__ page.js
    

    Here, '@user' and '@team' act as containers for different content, allowing us to design our website more flexibly.

    • How Layouts Use Slots as Props: Based on the documentation, the layout within the same route segment can utilize these slots as props. Here’s a clear example:
    export default async function Layout({ children, user, team }) {
      const userType = getCurrentUserType();
      return (
        <>
          {userType === 'user' ? user : team}
          {children}
        </>
      );
    }
    

    Note: In the above code, the getCurrentUserType() function is used to determine the type of user, which in turn dictates whether the user or team slot is displayed.

  • Implicit vs. Explicit Route Slots:

    One of the strong points of Next.js routing is its flexibility. While '@user' and '@team' in our example are explicit slots we define (linked directly to a @folder), there's also an implicit or automatic slot.
    The documentation explains that the

    "children is this kind of automatic slot, and we don't need to associate it with a @folder. Hence, dashboard/page.js functions the same as dashboard/@children/page.js."

By thoroughly grasping how Parallel Routes operate, developers can optimize the capabilities of Next.js 13, crafting websites that are more intuitive and adaptable.


5. A Step-by-step Guide On How To Use Parallel Routes

5.1 Setting Up a New Next.js App

Begin by creating a new Next.js application:

npx create-next-app@latest parallel-routes
Enter fullscreen mode Exit fullscreen mode

Navigate to the directory of the newly created app:

cd parallel-routes
Enter fullscreen mode Exit fullscreen mode

Start the development server:

yarn dev
Enter fullscreen mode Exit fullscreen mode

5.2 Structuring the App

In the project directory, create the following folders and files:

app
|__ @folder1
|____ page.js
|__ @folder2
|____ page.js
|__ page.js
|__ layout.js
Enter fullscreen mode Exit fullscreen mode

5.3 Creating The Comps And Simulating Data Loading

In app/@folder1/page.js, we will create the component to show and simulate a loading time to understand the visual sequence in which components load:

export default async function Page() {
  // simulate loading time for 6 seconds
  await new Promise(resolve => setTimeout(resolve, 6000));

  return <h4>FOLDER 1 COMPONENT LOADED</h4>
}
Enter fullscreen mode Exit fullscreen mode

Similarly, in app/@folder2/page.js:

export default async function Page() {
  // simulate loading time for 8 seconds
  await new Promise(resolve => setTimeout(resolve, 8000));

  return <h4>FOLDER 2 COMPONENT LOADED TWO SECONDS LATER</h4>
}
Enter fullscreen mode Exit fullscreen mode

These simulated loading times allow you to visually appreciate parallel routes' capability.

5.4 Update Layout Code

In app/layout.js, adjust the layout code to accommodate the two folders:

Before:

// ... (existing imports)
export default function RootLayout({ children }) {
  return (
    <html  lang="en">
      <body  className={inter.className}>{children}</body>
    </html>
  )
}
Enter fullscreen mode Exit fullscreen mode

After:

// ... (existing imports)
export default function RootLayout({ children, folder1, folder2 }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <div>
          {folder1}
        </div>
        <div>
          {folder2}
        </div>
        {children}
      </body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode

Feel free to style the layout the best you can for better readability

5.5 Add Loading States

Next.Js documentation states that

The special file loading.js helps you create meaningful Loading UI with React Suspense. With this convention, you can show an instant loading state from the server while the content of a route segment loads. The new content is automatically swapped in once rendering is complete.

For each component (folder1 and folder2), we will create a loading state. Your folder structure should be like this:

app
|__ @folder1
|____ page.js
|____ loading.js
|__ @folder2
|____ page.js
|____ loading.js
|__ page.js
|__ layout.js
Enter fullscreen mode Exit fullscreen mode

app/@folder1/loading.js

export default function Loading() {
  return <p>LOADING FOLDER 1...</p>
}
Enter fullscreen mode Exit fullscreen mode

app/@folder2/loading.js

export default function Loading() {
  return <p>LOADING FOLDER 2...</p>
}
Enter fullscreen mode Exit fullscreen mode

5.6. Modify the page

Adjust the content of app/page.js.
This modification ensures that the main page shows nothing, letting the parallel routes shine:

import Image from 'next/image'
import styles from './page.module.css'

export default function Home() {
  // anything you add here will be rendered as a children of RootLayout
  return null
}
Enter fullscreen mode Exit fullscreen mode

Disclaimer

While practicing with parallel routes, I found out that hot reloading did not display the routes as expected. I haven't investigated the issue so I can't tell you exaclty what the problem is.
If you encounter this, simply restart the development server to reflect the changes.

Now, you should be able to see something like this:

Example working

Conclusion

Parallel routes, introduced in Next.js 13.3, have marked a significant stride in the realm of web development.
Before their inception, developers faced challenges in displaying multiple segments of a website simultaneously, with traditional routing offering a more linear experience.
With parallel routes, Next.js offers an innovative approach to dynamic web design, allowing for simultaneous rendering of multiple pages in a single view.
This powerful feature not only provides enhanced user experience but also facilitates complex layouts and conditional renderings, pushing the boundaries of contemporary web application design.
By following up the detailed guide provided above, developers can dive deep into the workings of parallel routes, from understanding the core concepts like "slots" and the '@folder' convention to practical implementation using the Next.js framework.
While there might be a few bumps, such as the noted hot reloading issue, the flexibility and dynamism added to web applications by parallel routes make the learning curve worth it.
As the digital landscape continues to evolve, tools and features like these will undoubtedly play a pivotal role in shaping the future of web development.


Once again, thank you for your patience and dedication.
Got feedback or questions? Feel free to share. Every voice adds value.

Connect with me on:
dev.to community @leandro_nnz
hackernoon.com community @leandronnz
hashnode.com leandronnz
twitter.com @digpollution

Until next time, happy coding!


References

You can find the full code in this repo here
Official Next.js Documentation here
For building this article, I used StackEdit

Top comments (3)

Collapse
 
mabeleng profile image
mabelen.g@hotmail.com

Awesome post!

Collapse
 
leandro_nnz profile image
Leandro Nuñez

Thank you!

Collapse
 
aviyot profile image
aviyot

Greet.what if use component instead for this propose?