Need Help with Parallel routes
Answered
Korean bullhead posted this in #help-forum
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
But I'm not able to do this because
used like this inside the layout.tsx:
{/* 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}, etcBut 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
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"
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
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.
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 bullhead 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.
ah so if i understand it correctly u are passing the rsc props to a client component?
or atleast tried to
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.
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
why dont u put your static content directly into layout
they wont refetch when u change routes
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
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
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
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.
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
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>
)
}@Korean bullhead 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
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>
)
}
yes that looks good, and u was saying that its laggy and breaks after full refresh right?
@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 🤔
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
and for other routes where this won't be used I did a
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.tsxah 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
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 :)