Next.js Discord

Discord Forum

Need Help with Parallel routes

Answered
Korean bullhead posted this in #help-forum
Open in Discord
Korean bullheadOP
Hi, wanted to ask a nextjs question related to parallel routes. I have this app/layout.tsx
export default function RootLayout({
  children,
  experience,
  projects,
  blog,
  about,
}: Readonly<{
  children: React.ReactNode;
  experience: React.ReactNode;
  projects: React.ReactNode;
  blog: React.ReactNode;
  about: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${scientifica.className} antialiased bg-tokyo-night-background text-tokyo-night-foreground transition-colors`}
      >
        <Providers>
          <div className="grid grid-cols-4 grid-rows-7 gap-4 p-5 h-screen w-screen overflow-hidden">
            <NavigableDiv index={0} className="col-start-1 col-span-1 row-span-1 row-start-1">
              <BorderBox texts={[{ textYPosition: 'top', textXPosition: 'left', text: 'about' }]}>
                <About />
              </BorderBox>
            </NavigableDiv>
            <NavigableDiv index={1} className="col-start-1 col-span-1 row-span-2">
              <BorderBox texts={[{ textYPosition: 'top', textXPosition: 'left', text: 'pages' }]}>
                <RoutesList divIndex={1} />
              </BorderBox>
            </NavigableDiv>
            <NavigableDiv index={2} className="col-start-1 col-span-1 row-span-2">
              {/* Render a parallel route based on the current pathName */}
              <div></div>
            </NavigableDiv>
            <NavigableDiv index={3} className="col-start-1 col-span-1 row-span-2">
              <BorderBox texts={[{ textYPosition: 'top', textXPosition: 'left', text: 'socials' }]}>
                <SocialList divIndex={3} />
              </BorderBox>
            </NavigableDiv>
            <div className="col-start-2 col-span-3 row-span-7 row-start-1">
              {children}
            </div>
          </div>
        </Providers>
      </body>
    </html>
  );
}

84 Replies

Korean bullheadOP
here near the {/* Render a parallel route based on the current pathName */} I want to conditionally render a parallel routes using current path so basically like if I'm on /projects I render {projects} if on /blog I render {blog}, etc
But I'm not able to do this because usePathname() is only available inside a client side component, I tried to wrap this logic in a client side component and use that.. but it didn't work and no errors were logged as well..
'use client';
import { usePathname } from 'next/navigation';
import React from 'react';

interface LayoutListProps {
  experience: React.ReactNode;
  projects: React.ReactNode;
  blog: React.ReactNode;
  about: React.ReactNode;
}

const LayoutList: React.FC<Readonly<LayoutListProps>> = ({
  experience,
  projects,
  blog,
  about,
}) => {
  const pathName = usePathname();
  let content;
  switch (pathName) {
    case '/':
      content = <>{about}</>;
      break;
    case '/experience':
      content = <>{experience}</>;
      break;
    case '/projects':
      content = <>{projects}</>;
      break;
    case '/blog':
      content = <>{blog}</>;
      break;
    default:
      content = <div>Page not found</div>; // should not happen
  }
  return content;
};

export default LayoutList;

used like this inside the layout.tsx:
<LayoutList experience={experience} projects={projects} blog={blog} about={about} />
Korean bullheadOP
ok surprisingly this works fine in a prod build and with --turbo in dev mode
but doesn't with simple next dev
so ig this is a bug
@Korean bullhead so ig this is a bug
why arent u directly returning your passed in props
Korean bullheadOP
wdym?
by "returning your passed"
wait a sec
This is your RootLayout?
layout.tsx?
Korean bullheadOP
yeah
where do u get your props from? xD
Korean bullheadOP
parallel routes
@Korean bullhead by "returning your passed"
u are assigning it to a new value
let content
Korean bullheadOP
ah that
yeah I could do it either way
@Korean bullhead parallel routes
ah i see
so what didnt work exactly?
Korean bullheadOP
I want to conditonally render the parallel route based on the current route.
but for usePathName I need a client component.
I tried wrapping the conditional rendering logic in a client comonent and passing the parallel route props to it but that doesn't work.

I thought it worked in prod build but it is buggy and breaks by refreshing.
Korean bullheadOP
I don't even know?? if parallel routes should be even used here...

What I have is something like this currently:

The point of this was so I could have a loading.tsx and error.tsx inside the page and parallel route so when changing route the other static items aren't fetched again coz same layout but the dynamic stuff is fetched and a loading component is shown(from loading.tsx) similarly if error occurs error.tsx is used.
@gin or atleast tried to
Korean bullheadOP
yeah that's what I tried
Korean bullheadOP
the page.tsx one is easy. and works fine,

for the smaller div which I planned to use parallel routes, If I could I would use page.tsx

but inside layout.tsx I only have a single children
@gin they wont refetch when u change routes
Korean bullheadOP
that's what I am doing, please refer to the diagram.

for static content/stuff that only gets loaded once I am keeping that in layout.tsx
@Korean bullhead that's what I am doing, please refer to the diagram. for static content/stuff that only gets loaded once I am keeping that in layout.tsx
so that one div u are loading from a parallel route u want to have dynamic content based on the path?
uhm the thing i was thinking about is
u could wrap your parallel route into a dynamic segment
u can get the current path in your rsc then
the current segment
not the path sorry
app/dashboard/[slug]/page.tsx
Korean bullheadOP
ahh man Ik this sounds confusing.


I wish the following example explains what I really want inside the layout.tsx
const RootLayout = ({children}: any) => {
  return (
    <div>static</div>
    <div>dynamic content</div> {/*for one of the dynamic route I can simply use {children} */}
    <div>static</div>
    <div>dynamic content</div> {/*for this other dynamic route I need some way alongside inbuilt loading and error handling  */}
    <div>static</div>
    <div>static</div>
  )
}
I don't mind if the solution doesn't use parallel routes.. I just want a way I can do this nicely enough
both dynamic content are dependent on current route.
but from the example u showed me and the code u gave me
Korean bullheadOP
yeah,
at the end of day this is what I want on my page.

both dynamic content slots are dependent on current route and should have loading and error handling so if the inner component fails due to some or is loading I can render a loading state.
can u show me your current project structure?
app/
Answer
i cant really think of any other way what u was thinking ngl
in theory it should work
so idk
can you send me over your codebase?
@gin app/
Korean bullheadOP
ahh well it has a a lot of irrelevant stuff rn. but I can send the relevant stuff

each @something has a page.tsx error.tsx and loading.tsx
each something also has a page.tsx error.tsx and loading.tsx

This is how I planned to use it all in the root layout.tsx
const RootLayout = ({children, about, blog, projects, experience}: any) => {
  const pathName = // get current route somehow
  return (
    <div>static</div>
    {/*conditionally render the parallel route here*/} 
    <div>{if pathName === '/blog' && blog}</div>
    <div>static</div>
    {/* simply pass the page.tsx so if I go the /experience then /experience/page.tsx is loaded here */}
    <div>{children}</div>
    <div>static</div>
    <div>static</div>
  )
}
@gin can you send me over your codebase?
Korean bullheadOP
it's not pushed anywhere sorry unfortunately and don't want to push before I can get it barely working, I can send bits of whatever you want
and u implement default.tsx into your parallel routes?
or tried to
Korean bullheadOP
yeah I have done that
all parallel routes have a default.tsx
alr
and when passing all the routes to a client component and rendering from it breaks ur app?
but on turbo it works?
and on prod
if so, it sounds extremely weird i cant really help u further tbh xD it might actually be a bug in next so i suggest opening a github issue
@gin Click to see attachment
Korean bullheadOP
oh no wait!
you're right!
default.jsx does get rendered.

before all default.jsx had #Unknown Channel</>
now I added actual text to it and after a full refresh renders the default.tsx...


Though I don't want that 🤔
ok so another thing i can suggest
remove parallel routes completely
wrap your blog content inside a rsc wrapper
and render it that way
and use Suspense manually
Korean bullheadOP
omg lol
what needed was
@experience/experience/page.tsx so it work even after a hard refresh.
and for other routes where this won't be used I did a @experience/default.tsx
ah yeah
good
so basically people can go to /experience directly right?
and u can still use it as a parallel route
good idea
Korean bullheadOP
alot of uneccesary files and folders but ig this is nextjs
@gin so basically people can go to /experience directly right?
Korean bullheadOP
yeah
and now your clientside implementation works?
Korean bullheadOP
yup everything works fine now haha

https://nextjs-forum.com/post/1287177918371467367#message-1287194439856689226

this is what I really needed to read a bit harder

thanks a lot @gin
Korean bullheadOP
gn gin :)