Next.js 13 get current URL path in Server Component
This may be due to the current beta-phase of Next.js 13 app directory, but I am struggling to make a simple nav link with an active state based on the current path name–only with server components.
I assumed that there were an API to get the current pathname, just like you can get headers and cookies in Server Components. But alas, I couldn't find any.
I know this is possible to do with Client Components. But I wan't to keep the nav and its links server-side rendered for this example.
The only alternative I can think of is kind of hacky; create a middleware that sets a header (or cookie) that is then read from that SC. I don't need these routes to be statically rendered anyway.
I also tried to make a client-only provider component which would wrap around a nav link (rendered as a SC) and use tailwind's
group
feature, then use that group to set the nav link style based on the class name or state.
This didn't work, however this resulted in the following error:
It seems that rendering a client component that uses useRouter
or usePathname
inside a server component isn't allowed (or supported), even if I don't wrap it (???)
I am ok if I have to pass a prop from the layout into the main nav. That's not my main concern.24 Replies
Hey, I have kind of a solution
the full component I use is:
you use this inside of a server component, yes the link itself still renders as a client component
you just pass the values from the server component
sorry if it's not what you're looking for
Yeah, not what I was looking for since it's a client component. Thanks anyway.
I did figure out using the provider (I had a usePathname in my nav that is an SC, that's why it failed).
But really, I just wonder why we have to go through hoops to get such context.
Idk, for me personally, it makes all sense to use client components for links, buttons, etc.
And to pass data to them from SC
Hopefully you find a great workaround!
For me it doesn't, because they are non-interactive in terms of JS. They don't enhance the experience as they are just anchors.
For buttons, I'd rather use forms to handle data submissions. Makes logic a lot simpler and avoids a ton of footguns that comes with managing state and side effects.
holy crap. I can't believe this is even an issue. I was looking for this and it seems like there's a high demand for knowing the pathname in a server component but vercel dropped the ball on this
GitHub
[Next 13] Server Component + Layout.tsx - Can't access the URL / Pa...
Verify canary release I verified that the issue exists in the latest Next.js canary release Provide environment information Operating System: Platform: linux Arch: x64 Binaries: Node: 19.0.1 npm: 8...
The soloution I did was just add a
x-current-url
via my middleware for the headers()
to have access to
it works as expected
@humanest ^is
middleware.ts
in /app/middleware.ts
?yes core
root*
I'm seeing null when logging currentUrl
it should work, I used it the other day and remember it being something like that
hrm.. this is what I have
and seeing nothing logged for request and null logged for currentUrl 😦
I also tried your code verbatim using
"next/dist/client/components/headers";
I saw something similar posted here: https://stackoverflow.com/questions/75362636/how-can-i-get-the-url-pathname-on-a-server-component-next-js-13
Stack Overflow
How can I get the url pathname on a server component next js 13
So basically I have a server component in app dir and I want to get the pathname. I tried to do it using window.location but it does not work.
Is there any way I can do this?
the in the world are you passing the
request.headers
to new Headers()
look my at example above clearly 🤨that's from the linked solution. I tried yours too
I'll try yours again and paste it
well you're clearly doing something wrong, because I just strapped a new next 13 app and it worked
I literally copy/pasted your snippet now and it works
you're doing something else wrong
if it's not working
moving middleware.ts into /src from /src/app fixed it
man, I wish the docs were clearer...
it says the "root of the project". like does that mean it's colocated with package.json, which would be outside of src?
thanks for your help
root is root of
/app
or /pages
, I should've clarified that subconsciously 🤔meh. it's on vercel to disambiguate. the root can mean so many things up to the app/pages dir
well you can always open a PR on their docs now that they're Open-Source 🤔
good point