algolia / instantsearch

⚡️ Libraries for building performant and instant search and recommend experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/
MIT License
3.61k stars 505 forks source link

NextJs APP router instantsearch hooks rendering problem #5890

Open wesleyjanse opened 9 months ago

wesleyjanse commented 9 months ago

🐛 Current behavior

Using the experimental InstantSearchNext, I sometimes seem to get weird behaviour during rendering. In which not all of the content is directly rendered from the server, you will always see a flash of no content, followed by the hits rendering and then the refinements rendering, which gives a lot of CLS.

There is a codesandbox setup below, which reproduces the issue.

Video as proof of result: https://github.com/algolia/instantsearch/assets/38532331/31dfcc65-1040-4c7a-ad32-e3408f55947d

🔍 Steps to reproduce

  1. Go to the live codesandbox example
  2. Press a brand page
  3. Go back
  4. Press another brand page
  5. Notice that the layout is jumping around and not everyting is rendered correctly at the same time.

Live reproduction

https://codesandbox.io/p/sandbox/dank-hooks-t4w5d8

💭 Expected behavior

All content is SSR'd correctly.

Package version

"react-instantsearch": "^7.2.0",   "react-instantsearch-nextjs": "^0.1.2", 

Operating system

No response

Browser

No response

Code of Conduct

alexphiev commented 9 months ago

I can confirm a similar behavior when refining the results. For me, it almost always jumps back to default unrefined results. Is that the same for you? My searchClient is properly defined outside the component.

Using the react-instantsearch-router-nextjs like so:

<InstantSearch
      searchClient={searchClient}
      indexName={index}
      insights={false}
      future={{
        preserveSharedStateOnUnmount: true,
      }}
      routing={{
        router: createInstantSearchRouterNext({ singletonRouter }),
      }}
    >
      <SearchView />
</InstantSearch>
mverissimo commented 9 months ago

I'm facing the same problem, using hooks and components that depend on the context, eg: auto-complete-core, useSearchBox, useDynamicWidgets etc.

wesleyjanse commented 9 months ago

I have solved the initial loading issues/flickering, using "VirtualWidgets", for the dynamicWidgets. But I don't know if this has any downsides looking at requests, since I'm instantiating a virtual widget and a real widget for the refinementlits and dynamicwidgets.

mverissimo commented 9 months ago

@wesleyjanse this approach doesn't have any downside(I think), do you have a sandbox with your solution?

wesleyjanse commented 9 months ago

I need to free up some time for it, pretty stacked for now on work..

But i just created some virtual widgets, that use the hooks and return null.

And then imported those in the HOC. Seems to solve these issues for me.

aymeric-giraudet commented 8 months ago

Hi @wesleyjanse,

When you are navigating, the rendering is done client-side, you can check in the network tab it does not request documents and no HTML is received from the server. This is normal for CSR to flicker as queries are being made, React InstantSearch's default example does it

We would need to see with Next.js if it's possible to force server-side rendering on navigation, or perhaps for a way to transition only when requests are done

mverissimo commented 8 months ago

Hi @aymeric-giraudet you're right, this is expected behavior in CSR environment, but not in SSR(is my case), right?

fcasibu commented 2 months ago

Seems like this issue is still open and I'm having the same problem so might as well:

Using react-instantsearch-nextjs@0.2.4

Issue: Delayed rendering with client side navigation. As an example navigating from Home -> Search, Algolia does not seem to have any results yet for a bit of time, but going directly to Search has results immediately, so this seems to only happen through client side navigation

Repo: https://github.com/fcasibu/algolia-test

Is this a known problem with the app router? Is there a way to fix this because ideally we want immediate results after navigation. (Using a tag for hard navigation instead of Link is not an option)

Solved this by just searching once in the server:

    const initialSearchResult = await helper.searchOnce({
      // stuff
    });
   <Component initialSearchResult={JSON.parse(JSON.stringify(initialSearchResult.content))} /> // JSON.parse(JSON.stringify()) so it works with passing the object from server -> client components

and using it as follows:

  const { results: r } = useHits();
  const results =
    r.hits.length // not really ideal of a condition
      ? r
      : initialSearchResult;

But is this really ideal?

I missed this reply:

Hi @wesleyjanse,

When you are navigating, the rendering is done client-side, you can check in the network tab it does not request documents and no HTML is received from the server. This is normal for CSR to flicker as queries are being made, React InstantSearch's default example does it

We would need to see with Next.js if it's possible to force server-side rendering on navigation, or perhaps for a way to transition only when requests are done

Do you perhaps have any updates on this? @aymeric-giraudet

sefai commented 6 days ago

6275 may have resolved this, what do you think @aymeric-giraudet?

fcasibu commented 6 days ago

Latest changes made it worse for me where it does not even render in the server anymore 😓

aymeric-giraudet commented 6 days ago

@fcasibu

Sorry about this, may I get a reproduction to see what goes wrong ?

Regarding the CSR issue, I've seen your solution and while this works if you know params ahead of time, we can't integrate this into the library as there is no way to infer query params from the React tree in a server component. On our end we have to make use work on the browser, meaning a big overhaul on how we instantiate promises, React core team has started documenting a bit more about how to do that but we won't be able to ship a proper solution until React 19 ships.

fcasibu commented 6 days ago

Thanks for the fast response @aymeric-giraudet I'll try to create a reproducible example when I get some time.