Server client html mismatch occurs on first renderSee original GitHub issue
Warning: Expected server HTML to contain a matching <button> in <div>. occurs because html was rendered with no url params on server side, but rendered with url params in client side.
I think Next.js handles this problem by setting router.query to an empty object on the first render, and sets client url params on the next render. But because useUrlState uses window.location.search and not router, this warning occurs.
This can be avoided by using code like this:
const [queryState, setQueryState] = useQueryState(...); const [state, setState] = useState(); useEffect(() => setState(queryState), [queryState]);
But it would be better if this boilerplate could be avoided in some way.
- Created 10 months ago
- Comments:5 (1 by maintainers)
Top GitHub Comments
I think the correct solution would be to always return the default value on both server and client-side on the initial render. Reading from
window.location should be done in an effect. See this article for an in-depth explanation of why this is important https://joshwcomeau.com/react/the-perils-of-rehydration/
Unfortunately the Next.js router does not expose querystring params in the render tree in SSR, so those should be treated as client-side only (just like you would for code that depends on local storage values for example).
While theoretically it could be possible to get this kind of information on “per request” SSR (ie: page with
getServerSideProps), other kinds of non-client renders (ISR, static optimisation at build time) are not attached to a request and therefore don’t have querystring parameters.