how to pass searchParams around in next app server components?

Hey guys, as the title says, how do you guys pass around searchParams without an incredible amount of prop drilling? I'm in a position where most of my app and fetches lives in server component land, which feels pretty ideal. The only thing is that with trees of server components, I'm forced to prop drill my params and searchParams into every component, which would've been fine, if it wasn't for the fact that there is already a solved pattern in client side react with context and stores. Does anyone else feel this way too and/or how do you go about this?
8 Replies
showduhtung
showduhtungOP2w ago
Tried nuqs, but nuqs' cache doesn't update on history replace
François Best
Do you have an example where the cache didn’t update? Did you enable sending updates to the server using shallow: false ? By default, updates are client-side only, and opt-in to go through the network if the server needs the search params https://nuqs.47ng.com/docs/options#shallow
Options | nuqs
Configuring nuqs
noblica
noblica2w ago
I don't think there's much you can do on server side. On client side you can use the useSearchParams() hook. How much prop drilling are we talking about BTW? If this was an issue for me, I would consider trimming down the tree of server components.
showduhtung
showduhtungOP2w ago
Yeah, this looks similar to my alternate solution to use history.push . I feel like this answer to trim down the server components tree into client components is just not a scalable solution. I have this one page that has like 12 queries going on, each pretty expensive, so I've opted to componentize them to localize and parallelize the queries. This also opens me up to use Suspense around them, for nice loading states. But with them so spread out, I'm finding myself passing searchParams to each and every component. Some parts it goes 3-4 layers down, which imo looks really stupid, especially when there's already a solved solution client side. And since url is considered to be the dynamic state of choice, I just wish there was some way to hook into it.
noblica
noblica2w ago
What do you mean by "not a scalable solution"? What is the scale you are dealing with? BTW: You can do parallel queries with Promise.all(), you don't have to move each query to an individual component for them to execute in parallel.
luis_llanes
luis_llanes2w ago
Using client components doesn’t mean you’re giving up the cool things about the server. You can still pre-render the client components on the server, in fact, that’s what Next.js does (both client and server components are rendered on the server for the first render). Also, you’re not giving up the loading states, if the operation is asynchronous you can use the “use()” API (React 19 tho) to unwrap a promise and it’ll continue to work just as fine, <Suspense> gets trigger I’ve been there, I tried to make my whole app a server components app because it was the new shiny thing and it meant less JavaScript on the client, blah blah blah. At the end the power of React lies on the Composition, you don’t need your whole app to be either Server Components or Client Components, composition lets you mix and match, however it’s convenient. If there’s a solved and trusted solution in the client side then go for it, use the server for the data loading and prefetching, and the client for the stuff React has been doing for years
the_real_ryan_knight
@showduhtung: Yeah I think you simply have a composition problem you are dealing with. I've been there too where you want to keep things all server components blah blah blah, but at the end of the day you just simply cannot without prop drilling, or creating a client component. I'm sure with enough home brewing you could come up with something... Id highly recommend changing your architecture of the features by utilizing client components as needed for search params. Its easy to get stuck on forcing what you want with server comps and I get it.
/usr/bin/cat
/usr/bin/cat5d ago
Thats sucha a great take!

Did you find this page helpful?