API Reference / InstantSearch.js / relevantSort
Signature
instantsearch.widgets.relevantSort({
  container: string|HTMLElement,
  // Optional parameters
  templates: object,
  cssClasses: object,
});

About this widget #

Virtual indices allow you to use Relevant sort, a sorting mechanism that favors relevancy over the attribute you’re sorting on. The relevantSort widget displays the current search mode when searching in a virtual replica index, and allows users to switch between Relevant and regular sorting, which is more exhaustive and can return less relevant results.

Examples #

1
2
3
instantsearch.widgets.relevantSort({
  container: '#relevant-sort',
});

Options #

container #
type: string|HTMLElement
Required

The CSS Selector or HTMLElement to insert the widget into.

1
2
3
instantsearch.widgets.relevantSort({
  container: '#relevant-sort',
});
templates #
type: object
Optional

The templates to use for the widget.

1
2
3
4
5
6
instantsearch.widgets.relevantSort({
  // ...
  templates: {
    // ...
  },
});
cssClasses #
type: object

The CSS classes to override.

  • root: the root element of the widget.
  • text: the text element for explanation.
  • button: the toggle button element.
1
2
3
4
5
6
7
8
9
10
instantsearch.widgets.relevantSort({
  // ...
  cssClasses: {
    root: 'MyCustomRelevantSort',
    button: [
      'MyCustomRelevantSort-button',
      'MyCustomRelevantSort-button--subclass',
    ],
  },
});

Templates #

button #
type: string|function
Optional

The template used for displaying the toggle button.

1
2
3
4
5
6
instantsearch.widgets.relevantSort({
  // ...
  templates: {
    button: 'Toggle',
  },
});
text #
type: string|function
Optional

The template used for displaying extra information.

1
2
3
4
5
6
instantsearch.widgets.relevantSort({
  // ...
  templates: {
    text: 'Click the button',
  },
});

HTML output#

1
2
3
4
5
6
<div class="ais-RelevantSort my-RelevantSort">
  <div class="ais-RelevantSort-text"></div>
  <button type="button" class="ais-RelevantSort-button">
    <span>See all results</span>
  </button>
</div>

Customize the UI with connectRelevantSort#

If you want to create your own UI of the relevantSort widget, you can use connectors.

It’s a 3-step process:

// 1. Create a render function
const renderRelevantSort = (renderOptions, isFirstRender) => {
  // Rendering logic
};

// 2. Create the custom widget
const customRelevantSort = instantsearch.connectors.connectRelevantSort(
  renderRelevantSort
);

// 3. Instantiate
search.addWidgets([
  customRelevantSort({
    // instance params
  })
]);

Create a render function#

This rendering function is called before the first search (init lifecycle step) and each time results come back from Algolia (render lifecycle step).

const renderRelevantSort = (renderOptions, isFirstRender) => {
  const {
    boolean isVirtualReplica,
    boolean isRelevantSorted,
    boolean canRefine,
    function refine,
    object widgetParams,
  } = renderOptions;

  if (isFirstRender) {
    // Do some initial rendering and bind events
  }

  // Render the widget
}

Render options #

isVirtualReplica #
type: boolean

Indicates whether the index is a virtual replica.

1
2
3
4
5
6
7
8
const renderRelevantSort = (renderOptions, isFirstRender) => {
  const { isVirtualReplica } = renderOptions;

  const container = document.querySelector('#relevant-sort');

  container.innerHTML = 'This index is a ' +
    (isVirtualReplica ? 'virtual replica' : 'standard replica');
};
isRelevantSorted #
type: boolean

Indicates whether the search result is relevantly sorted out.

1
2
3
4
5
6
7
8
const renderRelevantSort = (renderOptions, isFirstRender) => {
  const { isRelevantSorted } = renderOptions;

  const container = document.querySelector('#relevant-sort');

  container.innerHTML = 'Showing ' +
    (isRelevantSorted ? 'relevant results.' : 'all results.');
};
canRefine #
type: boolean
Required

Indicates if search state can be refined.

1
2
3
4
5
6
7
8
const renderRelevantSort = (renderOptions, isFirstRender) => {
  const { canRefine } = renderOptions;

  if (!canRefine) {
    document.querySelector('#relevant-sort').innerHTML = '';
    return;
  }
};
refine #
type: function

Sets relevancyStrictness.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const isRelevantSortedRef = { current: undefined };

const renderRelevantSort = (renderOptions, isFirstRender) => {
  const { refine, isRelevantSorted } = renderOptions;
  isRelevantSortedRef.current = isRelevantSorted;

  const container = document.querySelector('#relevant-sort');

  if (isFirstRender) {
    const button = document.createElement('button');
    button.setAttribute('type', 'button');
    button.innerText = 'Toggle'

    button.addEventListener('click', () => {
      // `0`: show all results
      // `undefined`: fall back to the value from the index config.
      refine(isRelevantSortedRef.current ? 0 : undefined);
    });

    container.appendChild(button);
  }
};
widgetParams #
type: object

All original widget options forwarded to the render function.

1
2
3
4
5
6
7
8
9
10
11
12
13
const renderRelevantSort = (renderOptions, isFirstRender) => {
  const { widgetParams } = renderOptions;

  widgetParams.container.innerHTML = '...';
};

// ...

search.addWidgets([
  customRelevantSort({
    container: document.querySelector('#relevant-sort'),
  })
]);

Create and instantiate the custom widget#

We first create custom widgets from our rendering function, then we instantiate them. When doing that, there are two types of parameters you can give:

  • Instance parameters: they are predefined parameters that you can use to configure the behavior of Algolia.
  • Your own parameters: to make the custom widget generic.

Both instance and custom parameters are available in connector.widgetParams, inside the renderFunction.

const customRelevantSort = instantsearch.connectors.connectRelevantSort(
  renderRelevantSort
);

search.addWidgets([
  customRelevantSort({
    container: string|HTMLElement
    // Optional parameters
    templates: object
    cssClasses: object
  })
]);

Full example#

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
// Create a render function
const isRelevantSortedRef = { current: undefined }

const renderRelevantSort = (renderOptions, isFirstRender) => {
  const {
    isVirtualReplica,
    isRelevantSorted,
    refine,
    widgetParams,
  } = renderOptions;
  isRelevantSortedRef.current = isRelevantSorted;

  if (isFirstRender) {
    const button = document.createElement('button');

    button.addEventListener('click', () => {
      refine(isRelevantSortedRef.current ? 0 : undefined);
    });

    widgetParams.container.appendChild(button);
  }

  const button = widgetParams.container.querySelector('button');
  button.textContent =
    isRelevantSortedRef.current ? 'See all results' : 'See relevant results';
};

// create custom widget
const customRelevantSort = instantsearch.connectors.connectRelevantSort(
  renderRelevantSort
);

// instantiate custom widget
search.addWidgets([
  customRelevantSort({
    container: document.querySelector('#relevant-sort'),
  })
]);
Did you find this page helpful?