Error: NextRouter was not mounted.
antoine-lin opened this issue Β· comments
π Current behavior
Hi, I would like to setup SSR for Algolia using Next.js.
I got a bug with the usage of getServerState
from react-instantsearch-hooks-server
. I need to use useRouter
inside my page but when rendering to string server side the NextRouter
context is not mounted leading to this bug:
π Steps to reproduce
- Fork this codesandbox from documentation
- Import
useRouter
and use it inindex.tsx
- In Next.js 12 (which is the version in use in this sandbox) Next is not crashing but renders
null
on server when you console.logrouter
. In Next.js 13 the app is crashing.
Live reproduction
https://codesandbox.io/s/bug-reproduction-for-algolia-ssr-with-next-js-bmcpni?file=/pages/index.tsx
π Expected behavior
Initial state from SSR fetch should be resolved without crashing the application.
Having to use react-dom/server
inside getServerSideProps
seems to not be aligned with how Vercel designed it
Package version
react-instantsearch-hooks-server 6.39.3, react-instantsearch-hooks-web 6.39.1, next 13.1.6, react 18.2.0
Operating system
macOS Ventura 13.2
Browser
Chrome Version 109.0.5414.119 (Build officiel) (arm64)
Code of Conduct
- I agree to follow this project's Code of Conduct
Hi,
We retrieve the initial InstantSearch state by relying on React's renderToString
which renders the component outside of Next.js context. This means there are no possible access to its Hooks, like useRouter()
. While it defaulted to null
in the previous version, now it throws an Error.
Here are 2 options that have similar outcome (useRouter
is null
when rendered by renderToString
):
- you can wrap your reference to
useRouter
in atry {} catch() {}
clause - you can import
useRouter
fromnext/compat/router
which fallbacks to the previous behavior
Hi @dhayab thank you for your answer!
I think this solution is too "out of" Next.js. I would like, as much as possible, to rely on Next.js first class exported API.
For those who may face the same issue, I succeed to give correct initialResults
to InstantSearchSSRProvider
by fetching my indices inside getServerSideProps
using algoliasearch
SDK.
For the icing on the cake I wrapped it inside @tanstack/react-query to get my dehydrated state I retrieve in my front-end with the benefit of storing results inside react-query
cache.
The only downside is that you need to do hacky things to populate initialResults
like InstantSearchSSRProvider
is waiting for. You may need reduce manipulations.
As you found a solution, we'll close this issue, but we are aware and looking into ways we could expose the widgets without doing a render, or having a guide on how to expose all your necessary contexts in getServerState (Next doesn't really allow it), but that's tracked in other places already.
Thanks for making us further aware
Hi, @antoine-lin
Could you provide an example of how you get the initialResults
using algoliasearch
inside getServerSideProps
, please.