Next.js Discord

Discord Forum

Should I use parallel routes?

Answered
Rhinelander posted this in #help-forum
Open in Discord
RhinelanderOP
Layout.tsx
import { SidebarProvider } from "@/components/ui/sidebar";
import { auth } from "@/modules/auth/lib/auth";
import { DashboardNavbar } from "@/modules/dashboard/components/common/dashboard-navbar";
import { DashboardSidebar } from "@/modules/dashboard/components/common/dashboard-sidebar";
import { headers } from "next/headers";

type DashboardLayoutProps = {
  user: React.ReactNode;
  admin: React.ReactNode;
  partner: React.ReactNode;
};

export default async function DashboardLayout(props: DashboardLayoutProps) {
  const session = await auth.api.getSession({
    headers: await headers(),
  });

  if (!session || !session.user.role) {
    return null;
  }

  const { role } = session.user;

  return (
    <SidebarProvider>
      <DashboardSidebar />
      <main className="flex-1">
        <DashboardNavbar />
        {props[role as keyof typeof props]}
      </main>
    </SidebarProvider>
  );
}


Is this approach recommended? 75% stuff will be different between roles (different views)
Answered by joulev
so what happens when you go to a route is that, all page.tsx files corresponding to that route are all evaluated. @admin/.../page.tsx, @partner/.../page.tsx and @user/.../page.tsx are all ran and the outputs are put in the admin, partner and user slots respectively. you simply choose not to use two of the three slots, but those unused slots are still evaluated. that's the biggest problem with the parallel route approach.

nextjs doesn't have a compilation system that can analyse the code and figure out it can get away with not rendering the @admin/.../page.tsx file at all when a partner user is visiting.
View full answer

10 Replies

RhinelanderOP
"You can use Parallel Routes to conditionally render routes based on certain conditions, such as user role"
your page.tsx probably looks like this
export default async function AdminPage() {
  const user = await auth();
  // line A
  if (user.role !== "admin") return null;
  // line B
  ...
}

then in the parallel route system, line A will always be executed regardless of what role the user is. only line B is skipped if the role is not "admin".

so if you ensure the line A part of your application is always fast, it should be fine. but if the line A part of your application is slow for "partner", everyone will have to wait for that section and not just the partner users.

so yeah there is nuance to this and whether it's good or not depends a lot on how you write your routes. that's why this is not how i prefer to handle it. my preferences:

1. clear route structure e.g. admin user pages are always at /admin/* instead of sharing the same path with ordinary users

2. OR rewriting. e.g. rewriting / to /home for public users and to /dashboard for authenticated users, like how vercel.com and github.com are doing

3. OR conditional rendering: if (user.role === "admin") return <AdminStuff />. make it explicit and you don't risk making ordinary users wait for admin user requests.
RhinelanderOP
I prefer stuff that you just mentioned. It is very good approach, but I really like the way I can simply write routes without this routes starting with /:user-role/*. So I redirect users in if ther are authenticated - but I don't check roles. Roles I check in (dashboard)/layout.tsx - code above. I don't want to sacrifice performance but from the docs I couldn't clarify if @admin @partner @users are all rendered despite the role.
@Rhinelander I prefer stuff that you just mentioned. It is very good approach, but I really like the way I can simply write routes without this routes starting with /:user-role/*. So I redirect users in if ther are authenticated - but I don't check roles. Roles I check in (dashboard)/layout.tsx - code above. I don't want to sacrifice performance but from the docs I couldn't clarify if @admin @partner @users are all rendered despite the role.
so what happens when you go to a route is that, all page.tsx files corresponding to that route are all evaluated. @admin/.../page.tsx, @partner/.../page.tsx and @user/.../page.tsx are all ran and the outputs are put in the admin, partner and user slots respectively. you simply choose not to use two of the three slots, but those unused slots are still evaluated. that's the biggest problem with the parallel route approach.

nextjs doesn't have a compilation system that can analyse the code and figure out it can get away with not rendering the @admin/.../page.tsx file at all when a partner user is visiting.
Answer
RhinelanderOP
Aha now I understand. I wonder how much "evaluation costs in my example" - is there a way to test that?
@Rhinelander Aha now I understand. I wonder how much "evaluation costs in my example" - is there a way to test that?
it would be the time and resource required to run the Page function until the return statement – the line A in my example above. if your code immediately returns, the impact is negligible, but if your code runs expensive code before you return anything, that will be a wasted resource
RhinelanderOP
Thank you very much!