algolia / instantsearch

⚑️ Libraries for building performant and instant search and recommend experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.

Home Page:https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

InstantSearch SSR: Not able to get query params from URL with InstantSearch and Next

jrfilocao opened this issue Β· comments

πŸ› Current behavior

It has been driving me crazy for many days! I am not able to trigger SSR with a query from the URL:

Bildschirmfoto 2024-04-08 um 21 36 12

I have tried different options, read different articles like https://www.algolia.com/doc/guides/building-search-ui/going-further/server-side-rendering/react/ and https://www.algolia.com/doc/guides/building-search-ui/going-further/routing-urls/js/. I cannot get this to work.

I created a minimal codesandbox for this:

https://codesandbox.io/p/github/jrfilocao/bug-algolia/maincode-sandbox

πŸ” Steps to reproduce

  1. Open https://codesandbox.io/p/github/jrfilocao/bug-algolia/main
  2. Put these query params into the URL:
    ?sentences_pt_en%5Bquery%5D=bones
  3. Hit enter
  4. Check the console logs

Live reproduction

https://codesandbox.io/p/github/jrfilocao/bug-algolia/main

πŸ’­ Expected behavior

When entering ?sentences_pt_en%5Bquery%5D=bones, I should get results from the index having "bones" as content

Package version

"react-instantsearch-hooks-web": "^6.43.0",     "react-instantsearch-hooks-server": "^6.43.0",     "react-instantsearch-router-nextjs": "7.7.1",

Operating system

macOs

Browser

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Hi @jrfilocao,

It doesn't work because you need to have a widget that uses query in order for the parameter to be applied.
The simplest way would be to add a <SearchBox>, or if you don't want one to be rendered, you can use the hook to make what we call a "virtual widget" :

function VirtualSearchBox() {
  useSearchBox();

  return null;
}

And use it anywhere inside InstantSearch.

By the way, we've released React InstantSearch 7 which is just a rename of React InstantSearch Hooks, upgrading is pretty straightforward and we even have codemods to help : https://www.algolia.com/doc/guides/building-search-ui/upgrade-guides/react/#migrate-from-react-instantsearch-hooks-to-react-instantsearch-v7

Hi @aymeric-giraudet,
thank you so much for your answer. The VirtualSearchBox approach worked!

If I try adding a SearchBox, and change the text inside it, then the SSR effect disappears and I get client-side rendering and calls to Algolia like in the image. My goal is to avoid that, that's why I am using SSR in the first place. I do not want my customers to know which search engine I am using and even less that they get my ApiKey:

Bildschirmfoto 2024-04-09 um 19 32 47

Is there a way to instruct the SearchBox only to behave in an SSR fashion? I am new to the Javascript, next.js world. If I use the SSR approach, there is no way the customers can get my ApiKey right?

Hi @jrfilocao,

There's nothing sensitive about the Search API key, it can only perform searches, and it's exposed by most of our customers in production.

SSR only applies for the initial request, all subsequent server requests are then done with fetch (even when navigating to a new route, so that DOM state is not lost), and this is the case for every other Next.js app.

Making requests go through another server that then forwards to Algolia could make the search experience much slower than just going straight through Algolia's endpoints.

With all that said, I'm not recommending it, but here's a guide on how to implement a backend search : https://www.algolia.com/doc/guides/building-search-ui/going-further/backend-search/in-depth/backend-instantsearch/react/

This guide assumes you're using express, but you could do the same with Next.js API routes

Hi @aymeric-giraudet,

Thank you for your response. I was able to implement all of your suggestions and it worked! Now I have Server-Side Rendering (SSR) in place and search functionality in the backend:

https://github.com/jrfilocao/bug-algolia/blob/main/pages/index.js

However, I am trying to integrate the changes above into my actual prototype repository, and I am getting the following error:

image

I have tried everything, also took a look at:
algolia/react-instantsearch#3572

But I am not able to solve it.

I have added you as a contributor to https://github.com/jrfilocao/saci. Can you help me here?

Hey @aymeric-giraudet,

Could you please take a look at my comment? 😰

Thank you!!

Hi @jrfilocao,

I've had a look and the message gives correct information, the <InstantSearch> component was not mounted because you are conditionally rendering it based on if username from UserContext is defined or not. This is not an issue on our end. You should wrap into a context in getServerSideProps :

export async function getServerSideProps({ req }) {
  const protocol = req.headers.referer?.split("://")[0] || "http";
  const serverUrl = `${protocol}://${req.headers.host}${req.url}`;

  const serverState = await getServerState(
    <UserContext.Provider value={{ username: "somebody" }}>
      <SearchResult serverUrl={serverUrl} />
    </UserContext.Provider>,
    { renderToString }
  );

  return {
    props: {
      serverState,
      serverUrl,
    },
  };
}

Also since search page is hidden behind a login page, you may want to only render it client-side as server-side rendering is mostly for SEO purposes.

I will close this issue as I replied to the subject and solved it.

If you have further issues please refer to our docs : https://www.algolia.com/doc/ and you may contact our support if documentation is not clear enough.