Server-Side Rendering with React InstantSearch
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 tobundle.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
20
21
22
23
24
25
26
27
28
import React from 'react';
import { InstantSearch, SearchBox, Hits } from 'react-instantsearch-dom';
function App({
searchClient,
searchState,
resultsState,
onSearchParameters,
widgetsCollector,
...props
}) {
return (
<InstantSearch
{...props}
indexName="indexName"
searchClient={searchClient}
searchState={searchState}
resultsState={resultsState}
onSearchParameters={onSearchParameters}
widgetsCollector={widgetsCollector}
>
<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 toInstantSearch
.indexName
(required): the same index name that you pass toInstantSearch
.searchState
: the object that provides your initial state toresultsState
. It’s typically used for URL sync and could be set to{ query: 'chair' }
for example. Make sure thatApp
passes the initialsearchState
prop to yourInstantSearch
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 { liteClient as 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>
<div 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 { liteClient as 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.