Next.js Discord

Discord Forum

Props to navigation component in layout.tsx

Answered
Yellow-breasted Bunting posted this in #help-forum
Open in Discord
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 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 here
View full answer

19 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-side
you 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 flashes
but with useSearchParams for example there may be flashes in some circumstances
Yellow-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 🥴
with useEffect there will be flashes
Answer
@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!