Guides / Building Search UI / Going further

Server-Side Rendering

You are currently reading the documentation for React InstantSearch V6. Read our migration guide to learn how to upgrade from V5 to V6. You can still find the V5 documentation for this page.

Server-side rendering (SSR) typically improves SEO and performance. When using SSR, your initial web content is generated on the server: browsers download pages with HTML content already in place.

React InstantSearch is compatible with server-side rendering. We provide an API that works with any SSR solution.

Native

We split this guide into three parts:

  • App.js: the shared main React component between the server and the browser.
  • server.js: the main server entry to a simple Node HTTP server.
  • browser.js: the main browser entry (ultimately gets compiled to bundle.js).

App.js

App.js is the main entry point to your React application, it exports an App component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React from 'react';
import { InstantSearch, SearchBox, Hits } from 'react-instantsearch-dom';

function App({ searchClient, searchState, resultsState, onSearchParameters }) {
  return (
    <InstantSearch
      indexName="indexName"
      searchClient={searchClient}
      searchState={searchState}
      resultsState={resultsState}
      onSearchParameters={onSearchParameters}
    >
      <SearchBox />
      <Hits />
    </InstantSearch>
  );
}

export { App };

Exporting App makes the component available to both the browser and server code.

If you synchronize a searchState to the URL to create a proper routing, you need to pass the searchState to the InstantSearch component.

server.js

We provide an API called findResultsState, available in react-instantsearch-dom/server.

findResultsState is a function that retrieves a resultsState object that populates results in InstantSearch. The function takes two arguments:

  • The InstantSearch parent component that contains the widgets to mount on the page (App in this example).
  • A “props” object, which accepts:
    • searchClient (required): the same search client that you pass to InstantSearch.
    • indexName (required): the same index name that you pass to InstantSearch.
    • searchState: the object that provides your initial state to resultsState. It’s typically used for URL sync and could be set to { query: 'chair' } for example. Make sure that App passes the initial searchState prop to your InstantSearch component.
    • If you need to pass other props to the component, you can add them to the object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import React from 'react';
import { createServer } from 'http';
import { renderToString } from 'react-dom/server';
import algoliasearch from 'algoliasearch/lite';
import { findResultsState } from 'react-instantsearch-dom/server';
import { App } from './App';

const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');

const server = createServer(async (req, res) => {
  // You can get the full `searchState` in the `req` object
  const searchState = { query: 'chair' };
  // If you use a `SortBy` widget, the active index name is `searchState.sortBy`
  const indexName = 'INDEX_NAME';
  const resultsState = await findResultsState(App, {
    searchClient,
    searchState,
    indexName
  });
  const initialState = { searchState, resultsState };
  const html = renderToString(<App {...initialState} />);

  res.send(
    `
<!doctype html>
<html>
  <body>
    <h1>Awesome server-side rendered search</h1>
    <did id="root">${html}</div>

    <script>
      window.__APP_INITIAL_STATE__ = ${JSON.stringify(initialState)};
    </script>
    <!-- This is the build of `browser.js` -->
    <script src="bundle.js"></script>
  </body>
</html>
`
  );
});

server.listen(8080);

To use JSX and import statements, you must transpile your server-side code (e.g., with Babel). The __APP_INITIAL_STATE__ variable ensures that what was sent by the server matches what the browser expects (through a checksum).

browser.js

This last file creates the link between server-rendered code and the application on the browser.

1
2
3
4
5
6
7
8
9
10
11
import React from 'react';
import { render } from 'react-dom';
import algoliasearch from 'algoliasearch/lite';
import { App } from './App';

const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');

render(
  <App {...window.__APP_INITIAL_STATE__} searchClient={searchClient} />,
  document.querySelector('#root')
);

Express + ReactDOMServer

Express is a minimal and flexible Node.js web application framework. It’s widely adopted in the Node.js ecosystem. An example of React InstantSearch and Express is available on our GitHub repository.

Next.js

Next.js is a framework that wraps and abstracts the more complicated parts of SSR. An example of React InstantSearch and Next.js is available on our GitHub repository.

Did you find this page helpful?