algolia / react-instantsearch

⚡️ Lightning-fast search for React and React Native applications, by Algolia.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/react/
MIT License
1.97k stars 386 forks source link

SSR with a backend other than Node.js #2191

Closed babgyy closed 1 year ago

babgyy commented 5 years ago

I use React-Instantsearch with a Ruby on Rails backend. I would like to have the initial view rendered server-side for SEO reasons. But I can't find a way to make it work.

I can easily make an Algolia query server-side in ruby, get a JSON payload from the algoliasearch-rails gem with the raw_result method, however this does not work when given as a resultsState prop to InstantSearch.

Somebody had this same question 2 years ago. But I feel a lot of work has been done by Algolia since then to make this possible. Is it ?

How would you suggest doing SSR without

Is there a way to use findResultsState in my context ?

Is there any clear schema documentation for the resultsState prop ?

I have read InstantSearch's documentation of resultsState props that recommends to use findResultsState. Does this method have a Ruby / Rails equivalent ?

I have read the Server side rendering guide but it assumes I have a JS backend.

Any directions would be appreciated

Haroenv commented 5 years ago

This seems like a quite hard question to answer directly. Could you make a setup we can try out things in?

What kind of setup do you have to eventually render the react app?

babgyy commented 5 years ago

I have webpacker (webpack 3 preconfigured for rails common usecases)

React components are rendered with react-rails. This library consists mainly of ruby helper methods to trigger the mounting of React components on page loads, and to enable Server Side Rendering with ExecJS.

I will create a setup right now.

Haroenv commented 5 years ago

Since ExecJS doesn't support modules, I'd be surprised if it's possible this way, but interested to see what you have so far

babgyy commented 5 years ago

Here is a demo setup : https://github.com/babgyy/ssr-instantsearch-rails

I documented a bit how to setup and how to make it fail. As soon as I added a facet search, the feeding of React Instantsearch with JSON results from ruby began to fail. Activating SSR just produces the error sooner but fails the same way.

Since ExecJS doesn't support modules, I'd be surprised if it's possible this way, but interested to see what you have so far

In my understanding, Webpack & Babel handle modules and produce a JS edible by ExecJS

babgyy commented 5 years ago

Any opinion on this ?

Haroenv commented 5 years ago

Can you show where in that repository the SSR is actually happening?

Note that for resultsState to work, you'll need to make findResultsState (from SSR) work, or replicate it in the ruby part, which won't be easy at all, since a refinement list for example has multiple requests that are done. For that the algolia JS helper is used.

babgyy commented 5 years ago

Can you show where in that repository the SSR is actually happening?

Sure, as stated in the Argument section, SSR is handled by the react-rails gem. As a user of the gem, I "just" pass {prerendering: true} as an argument to the react_component ruby helper in the view app/views/welcome/index.html.erb

For more details on how this is all passed to ExecJS, we would have to drill into the implementation of the gem. Not uninteresting but irrelevant to this question in my opinion

Note that for resultsState to work, you'll need to make findResultsState (from SSR) work, or replicate it in the ruby part, which won't be easy at all, since a refinement list for example has multiple requests that are done. For that the algolia JS helper is used.

Precisely my point :) I understand that resultsState requires findResultsState. Which raises the following questions :

  1. is it possible to feed the InstantSearch with a JSON payload of results ?
  2. if not, how would you recommend doing SSR of InstantSearch with any other backend than a Node/JS backend ?
Haroenv commented 5 years ago

I recommend using node for server side rendering in general, you'll have a lot less headaches, and will always fit in the "simple path" of server side rendering. You can set up the server for server side rendering separately from your other backend easily.