Accessing params and pathname in a layout
Answered
Asian swamp eel posted this in #help-forum

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
--- 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
24 Replies

@Asian swamp eel 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?

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
--- 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
Answer

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
@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

you are not in the page. You are fully inside the layout:
It could look like this
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

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
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 :(

@Asian swamp eel so I basically need two componets per layout, then?

No, only one reusable component

Asian swamp eelOP
not really possible since the layouts are completely different - different areas of the application (public, admin, etc). nothing is really shared

for what do you need the pathname and for what the params? what are you trying to archive?

Asian swamp eelOP
pathname to make sidebar items active, params to get url slugs for building paths

Can you clarify both cases?

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

Asian swamp eelOP
2 have sidebars, but with different formats

how do you currently get the
user
variable?
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 }>;
}>) {

And how do you currently get the pathname?

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>
);
}

I am quite confused now... then you already accessing the params and the pathname inside your layout. So you initial issue is solved?

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

happy to help