Dynamic Rendering with InstantSearch.js
On this page
InstantSearch.js does not support server-side rendering (SSR). However, it is possible to get some of the SSR benefits using another technique: dynamic rendering.
Dynamic Rendering
In a nutshell, dynamic rendering allows to switch between client-side rendered and pre-rendered content for specific user agents, namely search engines user agents. This means that whenever your server receives a requests, it first looks at the user agent to determine whether it’s coming from a search engine or a regular user.
- If the request is coming from a search engine, the response is proxied through a headless browser that pre-renders it.
- If the request is coming from a regular user, the response is rendered client-side.
Build an InstantSearch app
The easiest way to setup a basic InstantSearch app is using create-instantsearch-app
.
Install create-instantsearch-app and create your app.
$
$
npm install -g create-instantsearch-app@latest
create-instantsearch-app my-app
Feel free to pick any InstantSearch flavor your like. Pick the default values for the rest of the options.
Run the build command and confirm it produced a dist/
folder.
$
$
cd my-app
npm run build
Add a basic Express.js server that will serve our static files.
$
$
npm install --save express
touch index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// index.js
const express = require('express');
const app = express();
app.use(express.static('dist'));
const port = process.env.PORT || 3000;
app.listen(port, err => {
if (err) {
console.error('failed to start server.');
return;
}
console.log(`server started at http://localhost:${port}/`);
});
Now run the server and visit http://localhost:3000 to make sure everything is working.
$
node index.js
Set up and configure a dynamic renderer
Google recommends using either rendertron (free, self-hosted) or prerender.io (fully hosted). In this example, we’ll be using rendertron.
$
$
npm install -g rendertron
PORT=3001 rendertron &
Our pre-renderer is now listening on port 3001
and ready to render JavaScript generated content into HTML.
Proxy your requests through Rendertron
You need to send every request with the Content-Type: text/html
header and the relevant user agent to the URL of Rendertron: http://localhost:3001/render
.
Depending on your stack, there are multiple ways you can achieve this kind of proxying, but if you’re using an Express.js server, rendertron-middleware can handle this proxying for you.
$
npm install --save rendertron-middleware
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const rendertronMiddleware = require('rendertron-middleware');
/* ... */
app.use(
rendertronMiddleware.makeMiddleware({
proxyUrl: `http://localhost:3001/render/`, // rendertron address with a /render/ suffix
timeout: 60 * 1000,
userAgentPattern: /googlebot|bingbot/i // by default
})
);
app.use(express.static('dist'));
/* ... */
Feel free to adjust the userAgentPattern
or use the default values.
Close and restart your server, then run this curl command to confirm pre-rendering works.
$
curl --user-agent "googlebot" http://localhost:3000/