Props to navigation component in layout.tsx
Answered
Yellow-breasted Bunting posted this in #help-forum
Yellow-breasted BuntingOP
Hi, I have a nav component which has two different styles which should be based on the slug of the page, but because it's in the root layout, theres no way to access this on the server-side... The only option I know is to move the nav component from the root
Does anyone have any ideas?
Thank you!
layout.tsx to each of the pages, which for me isn't an option because it risks some pages not having a nav. Does anyone have any ideas?
Thank you!
Answered by joulev
const path = usePathname();
const isHero = path === "/products/digital..."
// just use the isHero state here19 Replies
@Yellow-breasted Bunting Hi, I have a nav component which has two different styles which should be based on the slug of the page, but because it's in the root layout, theres no way to access this on the server-side... The only option I know is to move the nav component from the root `layout.tsx` to each of the pages, which for me isn't an option because it risks some pages not having a nav.
Does anyone have any ideas?
Thank you!
"use client";
export function Nav({ children }) {
const pathname = usePathname();
return (
<nav style={{ color: pathname === "/foo" ? "red" : "blue" }}>
{children}
</nav>;
);
}function Layout({ children }) {
return (
<html>
<body>
<Nav>
Hello world
</Nav>
{children}
</body>
</html>
);
}but because it's in the root layout, theres no way to access this on the server-sideyou can [access the slug directly](https://nextjs.org/docs/app/api-reference/file-conventions/layout#params-optional) in your root layout as well. You can access it like this:
export default function ShopLayout({
children,
params,
}: {
children: React.ReactNode
params: {
tag: string
slug: string
}
}) {
// URL -> /shop/shoes/nike-air-max-97
// `params` -> { tag: 'shoes', slug: 'nike-air-max-97' }
return <section>{children}</section>
}Yellow-breasted BuntingOP
Ohh thanks! I think in the root layout, the params are empty, but would work in a dynamic route layout e.g.
app/dashboard/[team]/layout.tsx though I might be missing something@joulev tsx
"use client";
export function Nav({ children }) {
const pathname = usePathname();
return (
<nav style={{ color: pathname === "/foo" ? "red" : "blue" }}>
{children}
</nav>;
);
}
tsx
function Layout({ children }) {
return (
<html>
<body>
<Nav>
Hello world
</Nav>
{children}
</body>
</html>
);
}
Yellow-breasted BuntingOP
This could be the solution! I'm using this at the moment but I'm getting a 'flash' of the state being incorrect, but it's probably the way I'm implementing the state
@Yellow-breasted Bunting This could be the solution! I'm using this at the moment but I'm getting a 'flash' of the state being incorrect, but it's probably the way I'm implementing the state
usePathname is guaranteed to be correct, so you probably are using something other than usePathname. what are you using?with
usePathname the value is immediately available and there are no flashesbut with
useSearchParams for example there may be flashes in some circumstancesYellow-breasted BuntingOP
const path = usePathname();
// check if path needs hero
useEffect(() => {
if (path === "/products/digital-menu-boards") {
setHero(true);
} else {
setHero(false);
}
}, [path]);I'm using useEffect 🥴
@Yellow-breasted Bunting Ohh thanks! I think in the root layout, the params are empty, but would work in a dynamic route layout e.g. `app/dashboard/[team]/layout.tsx` though I might be missing something
yes, I guess you have a dynamic part in your url like
[team] right?with
useEffect there will be flashes@Yellow-breasted Bunting
const path = usePathname();
// check if path needs hero
useEffect(() => {
if (path === "/products/digital-menu-boards") {
setHero(true);
} else {
setHero(false);
}
}, [path]);
I'm using useEffect 🥴
const path = usePathname();
const isHero = path === "/products/digital..."
// just use the isHero state hereAnswer
@B33fb0n3 yes, I guess you have a dynamic part in your url like [team] right?
Yellow-breasted BuntingOP
Actually the nav comp is in the root layout e.g.
app/(web)/layout.tsx so cant get any dynamic info :(Yellow-breasted BuntingOP
Thank you both!
Got it sorted, my problem was with useEffect, silly me 🥴
yeah you don't always need an effect https://react.dev/learn/you-might-not-need-an-effect
derived states for example never need an effect
Yellow-breasted BuntingOP
Yeah should be more if a client interacts with the page
I'll give it a read thanks!