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
:
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:
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!
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
:
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)
If you are not too lazy please support this discussion, maybe this will help to solve these issues in the future)
Top comments (3)
Simply that's not the purpose behind the parallel routes. I also had this problem at first, so I understand you, but with practice over time I realized that it was wrong in the way I approached its use.
I also have 2 similar problems. Have you found any solution?
Unfortunately no, I raised several times a discussion on gh, but no results yet...