Next.js Discord

Discord Forum

Accessing params and pathname in a layout

Answered
Asian swamp eel posted this in #help-forum
Open in Discord
Avatar
Asian swamp eelOP
I have a layout where I want to access URL parameters (params: Promise<{ name: string }> with const { name } = await params;) as well as use usePathname. To use usePathname I need my layout to be a client component, but to use params my function needs to be async. How can I access both in my layout?
Answered by B33fb0n3
you can access the params like you mentioned and create a client component that will be imported into your layout that uses the usePathname hook. If needed you can pass the parrams to the client component as well

--- Edit
Some code to this is here: https://nextjs-forum.com/post/1326094554906234901#message-1326102391988162662
Some explaination to this is here: https://nextjs-forum.com/post/1326094554906234901#message-1326102687871406121
View full answer

24 Replies

Answer
Avatar
Asian swamp eelOP
I don't quite understand - I need to use the params and the pathname in my layout directly, not within a page that uses the layout
Avatar
@Asian swamp eel I don't quite understand - I need to use the `params` and the `pathname` in my layout directly, not within a page that uses the layout
Avatar
you are not in the page. You are fully inside the layout:
export default async function Layout({
  params,
  children,
}: {
  params: Promise<{ team: string }>,
  children: React.ReactNode
}) {
  const team = (await params).team;

  return (
    <div>
        <ClientCompThatUsesPathname />
        <p>Some text</p>
        {children}
        // ...
    </div>
  )
}

It could look like this
Avatar
Asian swamp eelOP
Yeah, that works for the params, but I also need the pathname, which you get from usePathname()
but usePathname cannot be used in an async function
Avatar
@Asian swamp eel but `usePathname` cannot be used in an async function
Avatar
this component uses the usePathname hook (red arrow) 🙂
The green arrow is the page.tsx
Image
Image
Avatar
Asian swamp eelOP
so I basically need two componets per layout, then?
that does work, it just makes my app a bit messier.. I'm working with 4 different layouts, so that's 8 files for all the layouts :(
Avatar
@Asian swamp eel so I basically need two componets per layout, then?
Avatar
No, only one reusable component
Avatar
Asian swamp eelOP
not really possible since the layouts are completely different - different areas of the application (public, admin, etc). nothing is really shared
Avatar
for what do you need the pathname and for what the params? what are you trying to archive?
Avatar
Asian swamp eelOP
pathname to make sidebar items active, params to get url slugs for building paths
Avatar
Can you clarify both cases?
Avatar
Asian swamp eelOP
as an example:
              <SidebarMenuButton asChild isActive={pathname == "/admin/users/" + user + "/groups"}>
                <Link href={"/admin/users/" + user + "/groups"}>
                  <UsersIcon/>
                  Groups
                </Link>
              </SidebarMenuButton>

user comes from params
Avatar
Asian swamp eelOP
2 have sidebars, but with different formats
Avatar
how do you currently get the user variable?
Avatar
Asian swamp eelOP
the same way you do in your example above:
export default async function TestLayout({
  children,
  params,
}: Readonly<{
  children: React.ReactNode;
  params: Promise<{ user: string }>;
}>) {
Avatar
And how do you currently get the pathname?
Avatar
Asian swamp eelOP
like you showed - here's my entire component:
export default async function TestLayout({
  children,
  params,
}: Readonly<{
  children: React.ReactNode;
  params: Promise<{ user: string }>;
}>) {
  const { user } = await params;
  return (
    <SidebarProvider>
      <TestSidebar user={user}/>
      <SidebarInset>
        {children}
      </SidebarInset>
    </SidebarProvider>
  );
}
Avatar
I am quite confused now... then you already accessing the params and the pathname inside your layout. So you initial issue is solved?
Avatar
Asian swamp eelOP
it's solved now, yeah, after you showed me how it could be achieved. the only downside is that instead of being in one component it needs to be shoved into another one just to access the pathname
Avatar
happy to help