What is the most idiomatic way to show or hide something based on request pathname in NextJS 14?
Unanswered
troop4christ posted this in #help-forum
I have components that I wan't to show up in my
I'm trying to use the
But I'm seeing a behavior where a hidden component for a given pathname, if the user navigates to a different pathname, will stay hidden, even if it's supposed to show.. and vice versa..
It works fine on page load.. just not transitioning from one route/path to another.
I need a solution that will allow for SSR pages to still be renderable on the server and won't require client-side code like
layout.js
for all requested paths except for say /foo
and /bar/**
.. I'm trying to use the
middleware.js
x-pathname
header w/ next/headers
hack.. cough... workaround. // /middleware.js
const { pathname } = req.nextUrl
console.log(`pathname =>`, pathname)
// This is a workaround to pass the pathname to SSR pages
const requestHeaders = new Headers(req.headers)
requestHeaders.set('x-pathname', pathname)
// layout.js
import {headers} from 'next/headers'
const getReqPathname = async () => {
const headersList = headers()
console.dir([...headersList.entries()], { depth: 3, colors: true })
return headersList.get('x-pathname')
}
//JSX
const pathname = getReqPathname()
{ !pathname.startsWith('/foo') : <Component /> }
But I'm seeing a behavior where a hidden component for a given pathname, if the user navigates to a different pathname, will stay hidden, even if it's supposed to show.. and vice versa..
It works fine on page load.. just not transitioning from one route/path to another.
I need a solution that will allow for SSR pages to still be renderable on the server and won't require client-side code like
usePathname
or anything like that.4 Replies
@troop4christ I have components that I wan't to show up in my `layout.js` for all requested paths except for say `/foo` and `/bar/**` ..
I'm trying to use the `middleware.js` `x-pathname` header w/ `next/headers` hack.. *cough*... workaround.
javascript
// /middleware.js
const { pathname } = req.nextUrl
console.log(`pathname =>`, pathname)
// This is a workaround to pass the pathname to SSR pages
const requestHeaders = new Headers(req.headers)
requestHeaders.set('x-pathname', pathname)
javascript
// layout.js
import {headers} from 'next/headers'
const getReqPathname = async () => {
const headersList = headers()
console.dir([...headersList.entries()], { depth: 3, colors: true })
return headersList.get('x-pathname')
}
//JSX
const pathname = getReqPathname()
{ !pathname.startsWith('/foo') : <Component /> }
But I'm seeing a behavior where a hidden component for a given pathname, if the user navigates to a different pathname, will _stay_ hidden, even if it's supposed to show.. and vice versa..
It works fine on page load.. just not transitioning from one route/path to another.
I need a solution that will allow for SSR pages to still be renderable on the server and won't require client-side code like `usePathname` or anything like that.
Britannia Petite
I think Im having a very similar problem where I'm trying to conditionally load layouts based on the path they are on and its just fucking turbo aids. Correct me if I'm wrong but this should just straight up not be this hard to do, it's like an impossible feat just to properly load certain elements or element attributes in
Maybe you can try declaring your layout as a client component and then importing the async stuff somewhere else, I dont think that works though I genuinely have no idea
American black bear
usePathname then if pathname === something return null for elements you dont want
@American black bear that alone doesn't work for SSR pages/routes. It causes layout shift for SSR pages.
@Britannia Petite I ultimately had to leverage an
Inside of those components, set an initial
@Britannia Petite I ultimately had to leverage an
initPathname
prop into the components that I wanted to show/hide based on pathname. That prop would be fed by the x-pathname
hack mentioned above. Inside of those components, set an initial
show
state to that initPathname
prop, but then also leverage usePathname
, and then have a useEffect
that looks at the resultant client-side pathname
, and update the show
state accordingly whenever the route changed in the browser.