[Nextjs 14.1] Missing Suspense boundary with useSearchParams
Describe the bug
Using Next.js 14.1, build throws errors for bunch of pages, one of which was:
⨯ useSearchParams() should be wrapped in a suspense boundary at page "/404". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
Error occurred prerendering page "/_not-found". Read more: https://nextjs.org/docs/messages/prerender-error
I'm not using useSearchParams directly anywhere - that's why I came here.
Previous versions were throwing warning during build like:
Entire page /404 deopted into client-side rendering. https://nextjs.org/docs/messages/deopted-into-client-rendering /404
But now it throws errors - stopping build.
Possible solutions
- wrap
QueryParamProviderinSuspenselike:
"use client";
import { Suspense } from "react";
import NextAdapterApp from "next-query-params/app";
import { QueryParamProvider } from "use-query-params";
function QueryParamsProvider({ children }: { children: React.ReactNode }) {
return (
<Suspense>
<QueryParamProvider adapter={NextAdapterApp}>
{children}
</QueryParamProvider>
</Suspense>
);
}
export default QueryParamsProvider;
But, if we use it in root layout, it effectively will opt out from prerendering for all pages - works the same as with experimental flag they mention (which is discouraged).
If I took this custom QueryParamsProvider wrapper and put it as close to useQueryParam in the tree as possible (higher up the tree), it allowed 404 to be prerendered.
Not sure if this qualifies as bug, if this is fixable from library standpoint, it might just be tradeoff that you take into account then using it.
To Reproduce
Build any project using this library with Nextjs 14.1
Expected behavior
Build should pass.
i have ran into the same issue stated here, wrapping the provider in a suspense as @jrozbicki mentioned did seem to resolve it but if its possible to fix it at the lib level that would be awesome
But, if we use it in root layout, it effectively will opt out from prerendering
Why is this? I thought if you pass server components in as children, they will get prerendered along with whatever else is above the client query params context provider?
@sgoodrow I think Suspense will show fallback until client side bundle is loaded with useSearchParams, maybe wrong tho...
https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
Yeah, it's a bit unfortunate that this library has to call useSearchParams in the provider, which generally means a rather top-level component in your app. That turned out to not work so well with more recent developments on the Next.js side. As long as this library is based on use-query-params, we're a bit limited here.
Maybe we could work with the folks at use-query-params to ask for a new adapter API based on our findings here or we'd have to go for a new direction without use-query-params (maybe only using the base library serialize-query-params) and implement the React-specific part ourselves.
Either way seems like a bigger topic. I recently came across another query params library for Next.js: nuqs. Their API seems to be a better fit for modern Next.js (including support for RSC), I'm honestly wondering if we should deprecate next-query-params in favour of nuqs.
I'm open to suggestions though in case someone has other ideas!
Oh wow, nuqs looks fantastic.
I tried nuqs and I think we should combine forces and help move it along. It's currently not sufficiently testable with RTL as it doesn't use the mock-next-router capabilities. I'll be using next-query-params until then.