Server Side Rendering enables us to pre-render the results on the server enabling better SEO for the app, and faster delivery of relevant results on an initial render to the users.

Reactivesearch internally runs on a redux store. With Server Side Rendering, you can handle the intial render when a user (or search engine crawler) first requests your app. To achieve the relevant results on an initial render, we need to pre-populate the redux store of ReactiveSearch.

ReactiveSearch offers SSR via initReactivesearch() method which takes three params:

  • an array of all components (with their set of props) we wish to render at the server side
  • url params
  • base component (reactivebase) props

Usage

This is a three-steps process:

First, import initReactivesearch:

<script>import {initReactivesearch} from '@appbaseio/reactivesearch-vue';</script>

Then, evaluate the initial state:

const initialState = await initReactivesearch(...);

and finally, pass the computed initial state to ReactiveBase component.

<template>
    <reactive-base v-bind="settings" :initialState="initialState">
    ...
    </reactive-base>
</template>

Example

We will build a simple booksearch app with nuxt.js as an example to get started with:

Pre-requisites

Set up nuxt.js - Refer docs here

Installation

Use the package manager of your choice to install reactivesearch:

yarn add @appbaseio/reactivesearch-vue

Setup

Create an index.js file in the pages directory, and import initReactivesearch:

<script>import {initReactivesearch} from '@appbaseio/reactivesearch-vue';</script>

and we will also import the other relevant component from the reactivesearch library:

<script>
    import {
        ReactiveBase,
        DataSearch,
        SelectedFilters,
        ReactiveList,
} from '@appbaseio/reactivesearch';
</script>

Set the props for all the components we are going to use:

<script>
    const settings = {
        app: 'good-books-ds',
        credentials: 'nY6NNTZZ6:27b76b9f-18ea-456c-bc5e-3a5263ebc63d',
    };

    const dataSearchProps = {
        dataField: ['original_title', 'original_title.search'],
        categoryField: 'authors.raw',
        componentId: 'BookSensor',
        defaultSelected: 'Harry',
    };

    const reactiveListProps = {
        componentId: 'SearchResult',
        dataField: 'original_title.raw',
        from: 0,
        size: 5,
        renderItem: ({ data }) => `<div>${data.original_title}</div>`,
        react: {
            and: ['BookSensor'],
        },
    };
</script>

Next step is to evaluate the initial state in the asyncData lifecycle method:

<template>
    <reactive-base v-bind="settings" :initialState="initialState">
            <div className="row">
                <div className="col">
                    <data-search v-bind="dataSearchProps" />
                </div>

                <div className="col">
                    <selected-filters />
                    <reactive-list v-bind="reactiveListProps" />
                </div>
            </div>
    </reactive-base>
</template>
<script>
    export default {
        name: 'app',
        data: function() {
            return {
                settings,
                dataSearchProps,
                reactiveListProps
            };
        },
        async asyncData() {
            try {
                const initialState = await initReactivesearch(
                    [
                        {
                            ...dataSearchProps,
                            source: DataSearch,
                        },
                        {
                            ...reactiveListProps,
                            source: ReactiveList,
                        },
                    ],
                    null,
                    settings,
                );
                return {
                    initialState,
                    error: null,
                };
            } catch (error) {
                return {
                    initialState: null,
                    error,
                };
            }
        },
    };
</script>

Finally, you can now run the dev server and catch the SSR in action.

Example apps

You can check an example app here: