Skip to main content
This is the React InstantSearch v7 documentation. If you’re upgrading from v6, see the upgrade guide. If you were using React InstantSearch Hooks, this v7 documentation applies—just check for necessary changes. To continue using v6, you can find the archived documentation.
All Search and Discovery user interfaces display, in addition to a search box, a series of filters that allow users to narrow down their search. These onscreen filters are called facets. A typical facet is an attribute like “brand” or “price”, and facet values are the individual brands and prices. By clicking on a facet value, users can include and exclude whole categories of products. For example, by selecting “Blue” in the “Color” facet filter, a user can exclude every product except blue ones. For a long time, ecommerce websites have been displaying facets on the left side of the screen, allowing easy access. But this placement reduces the space available to display products. With the rise of mobile-first design and touchscreen, online businesses have started to display facets at the top of their product listing. That’s the case of Lacoste which increased its sales by +150% sales from Algolia’s search. Lacoste search interface with filters in drop-down menus Facet drop-down menus offer two benefits:
  • They increase facet visibility and accessibility, encouraging more usage.
  • They simplify the screen, leaving more room for products and creating more on-screen breathing space, an important UX design choice.
This guide shows how to turn a facet filter, commonly represented by a RefinementList or a HierarchicalMenu widget, into a drop-down menu layout.

Widget elements

By design, each facet drop-down menu widget has two elements:
  • A button with a label and the number of active refinements.
  • A panel (that can be toggled) containing the widget.
Both can be customized.
The facet drop-down menu widget can only contain one widget and is compatible with DynamicWidgets
Facet drop-down menu

Quickstart

1

Clone the code sample

To get started, clone the code sample and follow the instructions to install the dependencies, or fork the following CodeSandbox.In the project, you see two components:
  • Panel.tsx used as the drop-down menu that can be toggled. It also displays a header, wraps your provided widget and adds a footer on mobile.
  • FacetDropdown.tsx used to get the number of active refinements for the provided widget and close the panel when the search state has changed.
To use the facet drop-down menu widget in your own project: install or duplicate the dependencies for each widget (like the hooks folder and utils.ts file).
2

Use the facet drop-down menu widget

A basic usage of the facet drop-down menu widget:
React
<FacetDropdown>
  <RefinementList attribute="type" />
</FacetDropdown>;
The FacetDropdown widget automatically retrieves the attribute of the first provided child widget to display the number of current refinements in the drop-down menu toggle button. Facet drop-down menu showing the number of current refinements

Props

buttonText

Type: string | function You can use the buttonText prop to customize the text displayed in the drop-down menu button. It can be a string or a function. By default, it shows the number of active refinement for the provided widget. Here’s an example showing how you can get the current refinements to display the current bounds of a RangeInput widget.
React
<FacetDropdown
  buttonText={({ refinements }) => {
    const [start, end] = refinements;
    return start || end
      ? `Price (${(start || end).label}${end ? " & " + end.label : ""})`
      : `Price`;
  }}
>
  <RangeInput attribute="price" />
</FacetDropdown>;
Facet dropdown with a custom button text

closeOnChange

Type: boolean | function You can use the closeOnChange prop to close the drop-down menu as soon as users selects a facet value using a boolean or function that returns true. If it’s false, the drop-down menu isn’t closed automatically, allowing users to select more than one facet value. Here’s an example where the drop-down menu is automatically closed only if users are using a device with a width greater than or equal to 375px.
React
const MOBILE_WIDTH = 375;
/* ... */
<FacetDropdown closeOnChange={() => window.innerWidth >= MOBILE_WIDTH}>
  <RefinementList
    attribute="brand"
    searchable={true}
    searchablePlaceholder="Search..."
  />
</FacetDropdown>;

cssClasses

Type: Object You can use the classNames prop to add CSS classes on multiple elements of the facet drop-down menu widget. Here’s an example that adds custom CSS classes.
React
<FacetDropdown
  classNames={{
    button: "MyButton",
    buttonRefined: "MyButton--refined",
    closeButton: "MyCloseButton",
    mobileTitle: "MyMobileTitle",
  }}
>
  <RefinementList attribute="type" />
</FacetDropdown>;

Customize the UI

The generated markup lets you customize the look and feel to your needs, to change the default aspect of the drop-down menu with a few lines of CSS. Here’s the default version: An example of a search screen with facet dropdowns You can customize two aspects you can customize to your needs:
  • Inline facet values The demo’s brand drop-down menu widget uses an inline list. See the code in the App.css file. An example of a drop-down menu with inline facet values
    CSS
    .my-BrandDropdown .ais-RefinementList-list {
      width: 20rem;
      display: flex;
      flex-wrap: wrap;
    }
    
  • Fixed height drop-down menu The demo’s category drop-down menu widget is hierarchical and is a fixed height list. See the code in the App.css file. An example of facets with a fixed height drop-down menu
    CSS
    .my-CategoryDropdown .ais-HierarchicalMenu {
      height: 185px;
      overflow: auto;
    }
    

Mobile support

Mobile devices are already supported by the widget. Below 375px (this breaking point can be changed, see below):
  • The drop-down menu position is fixed and taking the full page size.
  • The page scroll is locked when the drop-down menu is open.
  • The button text is added as a title at the top of the drop-down menu.
  • A button to apply the changes is added at the bottom of the drop-down menu.
To customize the default behavior, the facet drop-down menu widget uses the following CSS media query:
CSS
@media only screen and (max-width: 375px) {
  /* ... */
}
It also uses the following logic to prevent page scrolling when the drop-down menu is open:
TypeScript
const isMobile = useMediaQuery("(max-width: 375px)");
useLockedBody(isOpened && isMobile);
This code sample gets you started by providing a basic look and feel for mobile devices. Refactor the provided code to match your current design and offer the best experience to your mobile users.
I