Guides / Building Search UI / UI & UX patterns

Facet Display in React InstantSearch

We released React InstantSearch Hooks, a new InstantSearch library for React. We recommend using React InstantSearch Hooks in new projects or upgrading from React InstantSearch.

This guide describes how to configure and order facets and their values using the dashboard and API, as well as how to enable the UI using InstantSearch or using a custom solution.

You can find this feature being described as “facet ordering”, “facet merchandising”, “dynamic widgets” or “dynamic facets”.

Managing facet display from the Algolia dashboard

The ability to control the facets to display and their order works by sending a dedicated renderingContent parameter alongside search results. This setting needs to be interpreted by the UI your users use to interact with the index.

There are three main implementation steps:

  1. Configuring the attributes to use for faceting on your search index.
  2. Configuring your facet display.
  3. Building a UI capable of interpreting the “renderingContent” setting. For this step, you can use the InstantSearch library which has widgets preconfigured. You can also build your UI using any other tools or platform, but you must rebuild the interpretation logic yourself.

Configuring your facet display using the dashboard

  1. Select the Search product icon on your dashboard and then select your index.
  2. Click the Configuration tab.
  3. Under the Filtering and Faceting category, click on Facet display.
  4. Click on the Add facet to display button to add the facets you want to display in your UI.
  5. Use the = icon next to each facet to drag them into the correct position. The facets in your UI are displayed in the same order as the order you define here.
  6. For each facet, click on the pen icon to configure how the engine should display the facet’s values. You can:

    • Pin some values at the top of the list if you want them to be displayed first.
    • Configure if the remaining values should be ordered by count, alphabetically, or if you want only to display the values pinned.
  7. To remove a facet from the list and stop displaying it in your UI, click on the trash icon.
  8. Don’t forget to save your changes.

Imagine you want to only display the facets “brand”, “size”, and “color” on your UI. The first step is to add those three facets to the list of facets to display. To be displayed in the list, they need to have already been configured as attributes for faceting.

With those three facets added, you want to ensure that users can easily browse through brands by displaying them alphabetically.

  • Since you have a specific partnership with the brand “Lacoste”, you want the brand to always display on top.
  • Sizes need to be in a specific order: S, M, L, XL. You may have sizes in different formats in your data, but for the sake of clarity, you only want to display those four. You pin them at the top in the correct order and choose not to display subsequent values
  • For colors, you want to display them by count and not pin any specific value.

As soon as you save the changes, the UI adapts to this new configuration.

This approach allows you to configure a static facet display. If, however, you want a more dynamic approach that customizes the display of the facets and values for a specific query or category, see the facet merchandising guide.

Configuring your facet display using the API

To apply the same configuration as in the preceding example, you need to apply the following settings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$index->setSettings([
  'renderingContent' => [
    'facetOrdering' => [
      'facets' => [
        'order' => ['brand', 'size', 'color']
      ],
      'values' => [
        'brand'=> [
          'order' => ['Uniqlo'],
          'sortRemainingBy' => 'alpha'
        ],
        'size'=> [
          'order' => ['S', 'M', 'L','XL'],
          'sortRemainingBy' => 'hidden'
        ],
        'color'=> [
          'sortRemainingBy' => 'count'
        ]
      ]
    ]
  ]
]);

Building the UI with InstantSearch

The fastest and simplest way to unlock the control of facet display directly from the Algolia dashboard is to build your UI using InstantSearch. This library already contains the widgets and logic needed to interpret the renderingContent parameter returned along search results and that contains the facet display information.

Upgrading InstantSearch

If you already built your UI using InstantSearch, you might still need to update it to leverage the dynamic widgets introduced in the latest versions. The facet display feature is compatible with InstantSearch starting with the following versions:

  • InstantSearch.js : available from version 4.32.0
  • Vue InstantSearch : available from version 4.1.0
  • React InstantSearch : available from version 6.14.0
  • InstantSearch iOS : available from version 7.12.0
  • InstantSearch Android : available from version 2.11.0

Check the upgrade guide for InstantSearch to upgrade your UI to the latest version.

Using InstantSearch

Once on a compatible version, make your UI compatible with the Facet Display feature:

  • Add refinement widgets for the different facets.
  • Add a DynamicWidgets container around the widgets you want to sort.
  • In those widgets, remove any custom sortBy you have or set facetOrdering to true.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
search.addWidgets([
  instantsearch.widgets.dynamicWidgets({
    container: '#dynamic-widgets',
    fallbackWidget: ({ container, attribute }) =>
      instantsearch.widgets.menu({ container, attribute, limit: 10 }),
    widgets: [
      container =>
        instantsearch.widgets.hierarchicalMenu({
          limit: 10,
          attributes: [
            'hierarchicalCategories.lvl0',
            'hierarchicalCategories.lvl1',
          ],
        }),
    ],
  }),
])

Preventing extra data being requested

When dynamicWidgets receives results, it mounts the selected widgets for that result. To avoid an initial search performing two network requests, the default value of dynamic widgets adds facets to ['*'].

You can avoid requesting all facets by making an initial network request. To do this, add facets: [] to dynamic widgets.

You can use this approach if there are many (>100) facet values that you don’t need to display. Instead of requesting all facets with a wildcard (*) only the facets that will be set up in facet ordering are requested.

A downside is that an extra network request happens on mount, so make sure to measure before applying this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
search.addWidgets([
  instantsearch.widgets.dynamicWidgets({
    container: '#dynamic-widgets',
    fallbackWidget: ({ container, attribute }) =>
      instantsearch.widgets.menu({ container, attribute, limit: 10 }),
    widgets: [
      container =>
        instantsearch.widgets.hierarchicalMenu({
          limit: 10,
          attributes: [
            'hierarchicalCategories.lvl0',
            'hierarchicalCategories.lvl1',
          ],
        }),
    ],
    // do two network requests
    facets: []
  }),
])

Building the UI without InstantSearch

If you aren’t using InstantSearch to build your UI, you need to build within your front end the logic to:

  • interpret the renderingContent parameter returned along search results,
  • and order your facets and values based on your interpretation of the renderingContent parameter values.

There are two steps to the custom implementation of front-end search:

Reading the facet order.

If you hard code the list of facets to display on a page, you now can read that from result.renderingContent.facetOrdering.facets.order (all keys are optional). This is the list of attributes that you chose to display, and can be looped over to display individual facet lists.

Reading the facet value order

You still need to list the attribute you want to display facets of in searchParameters.facets, and will also read the possible results from result.facets[facetName]. However the difference now is that after fetching those values, you can read the result.renderingContent.facetOrdering.values[facetName] object to sort those values. This object has the following keys:

  • order: this is an array of facet values to pin at the start of the list
  • sortRemainingBy: this is a string that describes how to sort the remaining values. Either “alpha” (alphabetically, ascending), “count” (value retrieved from facets[facetName][facetValue], descending) or “hidden”, which means to only display the ordered items.
Did you find this page helpful?