Problems with Parallel Routes in Next.js
Tags: learning, typescript, nextjs, javascript
Published: 2024-01-06 15:10:55

The Next.js 13.3 brought a new feature that calls the Parallel Routes which allows you to simultaneously or conditionally render one or more pages in the same layout. That is a really cool feature that may reduce the usage of react `<Suspense>` and improve the logic of data fetching in the app. **BUT**, I found that there are at least two problems with it and feel to share it

---

For now, let's take a look at how code looks like without parallel routes. For example for I have a dashboard route that looks like `app/projects/page.tsx`: 

```tsx
import { Suspense } from "react";

const ProjectsPage = async () => {
  return (
    <div>
      <Suspense fallback={<div>Loading Users...</div>}>
        <Users />
      </Suspense>
      <Suspense fallback={<div>Loading Projects List...</div>}>
        <ProjectsList />
      </Suspense>
    </div>
  );
};

export default ProjectsPage;

const Users = async () => {
  await new Promise((res) => setTimeout(res, 1000));
  return <h1>Users</h1>;
};

const ProjectsList = async () => {
  await new Promise((res) => setTimeout(res, 3000));
  return <h1>Projects</h1>;
};
```

The code is pretty obvious, we are seeing fallbacks until promises in components are resolved.

Now let's rewrite it using parallel routes. We will create two more folders inside `app/projects` that will be called `@users` and `@projectslist`. Each will contain `page.tsx` and `loading.tsx` which are component itself and loading fallback. And also the layout where we can use these components. In general, structure will look like: 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bgd1497bc7tata0bdk4.png)

```tsx
type LayoutProps = {
  children: React.ReactNode;
  projectslist: React.ReactNode;
  users: React.ReactNode;
};

const Layout = ({ children, users, projectslist }: LayoutProps) => {
  return (
    <div>
      {users}
      {projectslist}
      {children}
    </div>
  );
};

export default Layout;
```

That works pretty well ha? We have the same logic, do we? Then what are the `children` in our case? The `children` is our `page.tsx` inside the projects folder, and here is the first problem.

---

## First Problem

If we take a look at the original code, we will see that inside the projects page, we have two components however now these components are inside our layout. Soooo, what do I have inside the page since the components are not there? The answer is null!

```tsx
const ProjectsPage = () => null;

export default ProjectsPage;
```

The Next.js works so that it requires have page file inside a route to be able to render a page otherwise we receive an error. Sometimes it is annoying to create pages like this, but what to do...

---

## Second Problem

The Parallel Routes can be controlled by nested and dynamic routes it is also a cool feature. But sometimes it is not the best option...
The components from parallel routes live inside root layout for projects route. Let's say we want a page that will be rendered depending on the project id. For this we will create new page with path `app/projects/[projectId]/page.tsx`. When we try to reach this page we will receive an error. Answer on question why is: _Next.js will first try to render the unmatched slot's default.js file. If that's not available, a 404 gets rendered_. For us, it means that if we do not want to render these parallel components for our page we need to create new black pages for parallel routes were we return null: `app/projects/@projectslist/[projectId]/page.tsx` and `app/projects/@users/[projectId]/page.tsx`: 

```tsx
const Page = () => null;

export default Page;
```

Just imagine what folder hell awaits you when you have more than 2 parallel routes))

---

## Conclusion

Nonetheless, Parallel Routes is a very cool feature and definitely has cases where it is better to use it than just wrap a component in react `<Suspense>`.  But for now, my choice is to use `<Suspense>` if I have nested routes))) Hope this was informative for you! See ya)

---

## Sources

- [Next.js documentation](https://nextjs.org/docs/app/building-your-application/routing/parallel-routes)