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.
Signature
<RefinementList
  attribute={string}
  // Optional parameters
  operator={'and' | 'or'}
  limit={number}
  showMore={boolean}
  showMoreLimit={number}
  searchable={boolean}
  searchablePlaceholder={string}
  sortBy={string[] | function}
  escapeFacetValues={boolean}
  transformItems={function}
  classNames={object}
  translations= {object}
  ...props={ComponentProps<'div'>}
/>

Import

JavaScript
import { RefinementList } from "react-instantsearch";

About this widget

<RefinementList> is a widget that lets users filter the dataset using multi-select facets. A refinement list only displays the most relevant facet values for the current search context. The sortBy option only affects how the facets are ordered, not which facets are returned. This widget includes a “search for facet values” feature, enabling users to search through the values of a specific facet attribute. This makes it easy to find uncommon facet values.
The attribute provided to the widget must be in attributes for faceting, either on the dashboard or using the attributesForFaceting parameter with the API.If you are using the searchable prop, you also need to make the attribute searchable using the dashboard or using the searchable modifier of attributesForFaceting with the API.

Disappearing facet values

With many facet values, the available options can change depending on the user’s query. The refinement widget displays the most common facet values for a given query. A user’s chosen value can vanish if they alter the query. This occurs because only the most common facet values are displayed when there are many options. A previously selected value might not appear if it’s uncommon for the new query. To also show less common values, adjust the maximum number of values with the configure widget. It doesn’t change how many items are shown: the limits you set with limit and showMoreLimit still apply.

How to implement a “Show more” feature

A custom useRefinementList widget displays up to showMoreLimit refinement items. You can sort the items as desired before they’re trimmed. However, you’ll need to slice to the appropriate limit and keep track of isShowingMore in the local state:
JavaScript
const CustomRefinementList = connectRefinementList(function RefinementList({
  items,
  limit,
  showMoreLimit,
}) {
  const [isShowingMore, toggleShowMore] = React.useState(false);
  const itemsToDisplay = items.slice(0, isShowingMore ? showMoreLimit : limit);

  // render using `itemsToDisplay`
});
You can also create your own UI with useRefinementList.

Examples

JavaScript
import React from "react";
import { liteClient as algoliasearch } from "algoliasearch/lite";
import { InstantSearch, RefinementList } from "react-instantsearch";

const searchClient = algoliasearch("YourApplicationID", "YourSearchOnlyAPIKey");

function App() {
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <RefinementList attribute="brand" />
    </InstantSearch>
  );
}

Props

attribute
string
required
The name of the attribute in the records.To avoid unexpected behavior, you can’t use the same attribute prop in a different type of widget.
JavaScript
<RefinementList attribute="categories" />;
operator
'and'|'or'
default:"'or'"
How the facets are combined.
  • 'or': Returns results matching any of the selected values.
  • 'and': Returns results matching all selected values.
Use filters or facet filters for more complex result refinement.
JavaScript
<RefinementList
  // ...
  operator="and"
/>;
limit
number
default:10
How many facet values to retrieve.When you set showMore and showMoreLimit, this is the number of facet values to display before clicking the Show more button.
JavaScript
<RefinementList
  // ...
  limit={5}
/>;
showMore
boolean
default:false
Whether to display a button that expands the number of items.
JavaScript
<RefinementList
  // ...
  showMore={true}
/>;
showMoreLimit
number
The maximum number of items to display if the widget is showing more items.
JavaScript
<RefinementList
  // ...
  showMoreLimit={20}
/>;
searchable
boolean
default:false
Whether to add a search input to let users search for more facet values.You need to make the attribute searchable using the dashboard) or using the searchable modifier of attributesForFaceting with the API.
In some situations, refined facet values might not be present in the data returned by Algolia.
JavaScript
<RefinementList
  // ...
  searchable={true}
/>;
searchablePlaceholder
string
The value of the search input’s placeholder.
JavaScript
<RefinementList
  // ...
  searchablePlaceholder="Search our products"
/>;
sortBy
string[] | (a: FacetValue, b: FacetValue) => number
How to sort refinements. Must be one or more of the following strings:
  • "count" (same as "count:desc")
  • "count:asc"
  • "count:desc"
  • "name" (same as "name:asc")
  • "name:asc"
  • "name:desc"
  • "isRefined" (same as "isRefined:asc")
  • "isRefined:asc"
  • "isRefined:desc"
You can also use a sort function that behaves like the standard JavaScript compareFunction.When you don’t set this parameter, and you’ve set facetOrdering for this facet in renderingContent, facets are sorted using facetOrdering and use the default order as a fallback.
In some situations, refined facet values might not be present in the data returned by Algolia.
<RefinementList
  // ...
  sortBy={["count:desc", "name:asc"]}
/>;
escapeFacetValues
boolean
default:true
Escapes the content of the facet values returned by Algolia.When using this parameter, the highlighting tags are always mark.
JavaScript
<RefinementList
  // ...
  escapeFacetValues={false}
/>;
transformItems
(items: object[], metadata: { results: SearchResults }) => object[]
A function that receives the list of items before they are displayed. It should return a new array with the same structure. Use this to transform, filter, or reorder the items.The function also has access to the full results data, including all standard response parameters and parameters from the helper, such as disjunctiveFacetsRefinements.
const transformItems = (items) => {
  return items.map((item) => ({
    ...item,
    label: item.label.toUpperCase(),
  }));
};

function Search() {
  return (
    <RefinementList
      // ...
      transformItems={transformItems}
    />
  );
}
classNames
Partial<RefinementListClassNames>
The CSS classes you can override and pass to the widget’s elements. It’s useful to style widgets with class-based CSS frameworks like Bootstrap or Tailwind CSS.
  • root. The root element of the widget.
  • noRefinementRoot. The root element when there are no refinements.
  • searchBox. The search box element.
  • noResults. The root element of the widget when there are no results.
  • list. The list element.
  • item. Each item element.
  • selectedItem. Each selected item element.
  • label. The label of each item.
  • checkbox. The checkbox of each item.
  • labelText. The text element of each label.
  • count. The count of each item.
  • showMore. The “Show more” button.
  • disabledShowMore. The disabled “Show more” button.
JavaScript
<RefinementList
  // ...
  classNames={{
    root: "MyCustomRefinementList",
    searchBox:
      "MyCustomRefinementListSearchBox MyCustomRefinementListSearchBox--subclass",
  }}
/>;
translations
Partial<RefinementListTranslations>
A dictionary of translations to customize the UI text and support internationalization.
  • submitButtonTitle. The submit button title of the search box.
  • resetButtonTitle. The reset button title search box.
  • noResultsText. The text to display when searching for facets returns no results.
  • showMoreButtonText. The text for the “Show more” button.
JavaScript
<RefinementList
  // ...
  searchable
  showMore
  translations={{
    submitButtonTitle: "Submit",
    resetButtonTitle: "Reset",
    noResultsText: "No brands matching your query.",
    showMoreButtonText({ isShowingMore }) {
      return isShowingMore ? "Show less brands" : "Show more brands";
    },
  }}
/>;
...props
React.ComponentProps<'div'>
Any <div> prop to forward to the root element of the widget.
JavaScript
<RefinementList
  // ...
  className="MyCustomRefinementList"
  title="My custom title"
/>;

Hook

React InstantSearch let you create your own UI for the <RefinementList> widget with useRefinementList. Hooks provide APIs to access the widget state and interact with InstantSearch. The useRefinementList Hook accepts parameters and returns APIs. It must be used inside the <InstantSearch> component.

Usage

First, create your React component:
JavaScript
import { useRefinementList } from "react-instantsearch";

function CustomRefinementList(props) {
  const {
    items,
    hasExhaustiveItems,
    createURL,
    refine,
    sendEvent,
    searchForItems,
    isFromSearch,
    canRefine,
    canToggleShowMore,
    isShowingMore,
    toggleShowMore,
  } = useRefinementList(props);

  return <>{/*Your JSX*/}</>;
}
Then, render the widget:
JavaScript
<CustomRefinementList {...props} />;

Parameters

Hooks accept parameters. You can either pass them manually or forward props from a custom component.
When passing functions to Hooks, ensure stable references to prevent unnecessary re-renders. Use useCallback() for memoization. Arrays and objects are automatically memoized.
attribute
string
required
The name of the attribute in the records.To avoid unexpected behavior, you can’t use the same attribute prop in a different type of widget.
JavaScript
const refinementListApi = useRefinementList({
  attribute: "categories",
});
operator
'and'|'or'
default:"or"
How the filters are combined.
  • 'or': Returns results matching any of the selected values.
  • 'and': Returns results matching all selected values.
JavaScript
const refinementListApi = useRefinementList({
  // ...
  operator: "and",
});
limit
number
default:10
How many facet values to retrieve.When you set showMore and showMoreLimit, this is the number of facet values to display before clicking the Show more button.
JavaScript
const refinementListApi = useRefinementList({
  // ...
  limit: 5,
});
showMore
boolean
default:false
Whether to display a button that expands the number of items.
JavaScript
const refinementListApi = useRefinementList({
  // ...
  showMore: true,
});
showMoreLimit
number
The maximum number of items to display if the widget is showing more items.
JavaScript
const refinementListApi = useRefinementList({
  // ...
  showMoreLimit: 20,
});
sortBy
string[] | (a: FacetValue, b: FacetValue) => number
How to sort refinements. Must be one or more of the following strings:
  • "count" (same as "count:desc")
  • "count:asc"
  • "count:desc"
  • "name" (same as "name:asc")
  • "name:asc"
  • "name:desc"
  • "isRefined" (same as "isRefined:asc")
  • "isRefined:asc"
  • "isRefined:desc"
You can also use a sort function that behaves like the standard JavaScript compareFunction.When you don’t set this parameter, and you’ve set facetOrdering for this facet in renderingContent, facets are sorted using facetOrdering and use the default order as a fallback.
In some situations, refined facet values might not be present in the data returned by Algolia.
const refinementListApi = useRefinementList({
  // ...
  sortBy: ["count:desc", "name:asc"],
});
escapeFacetValues
boolean
default:true
Escapes the content of the facet values returned by Algolia.When using this parameter, the highlighting tags are always mark.
JavaScript
const refinementListApi = useRefinementList({
  // ...
  escapeFacetValues: false,
});
transformItems
(items: object[], metadata: { results: SearchResults }) => object[]
A function that receives the list of items before they are displayed. It should return a new array with the same structure. Use this to transform, filter, or reorder the items.The function also has access to the full results data, including all standard response parameters and parameters from the helper, such as disjunctiveFacetsRefinements.
const transformItems = (items) => {
  return items.map((item) => ({
    ...item,
    label: item.label.toUpperCase(),
  }));
};

function RefinementList() {
  const refinementListApi = useRefinementList({
    // ...
    transformItems,
  });

  return <>{/* Your JSX */}</>;
}

APIs

Hooks return APIs, such as state and functions. You can use them to build your UI and interact with React InstantSearch.
items
RefinementListItem[]
The list of filtering values returned by Algolia.
Type definition
type RefinementListItem = {
  /**
   * The value of the refinement list item.
   */
  value: string;
  /**
   * Human-readable value of the refinement list item.
   */
  label: string;
  /**
   * Human-readable value of the searched refinement list item.
   */
  highlighted?: string;
  /**
   * Number of matched results after refinement is applied.
   */
  count: number;
  /**
   * Indicates if the list item is refined.
   */
  isRefined: boolean;
};
hasExhaustiveItems
boolean
Whether the results are exhaustive.
createURL
(value: string) => string
Creates the next state URL of a selected refinement.
refine
(value: string) => string
Applies the selected refinement.
sendEvent
(eventType: string, facetValue: string, eventName?: string) => void
Sends an event to the Insights middleware.
searchForItems
(query: string) => void
Searches for values in the list.
Whether the values are from an index search.
canRefine
boolean
Whether a refinement can be applied.
canToggleShowMore
boolean
Whether the Show more button can be activated, meaning there are enough additional items to display, or already displaying over the limit items.
isShowingMore
boolean
Whether the menu is displaying all the menu items.
toggleShowMore
() => void
Toggles the number of values displayed between limit and showMoreLimit.

Example

import React from "react";
import { useRefinementList } from "react-instantsearch";

function CustomRefinementList(props) {
  const {
    items,
    refine,
    searchForItems,
    canToggleShowMore,
    isShowingMore,
    toggleShowMore,
  } = useRefinementList(props);

  return (
    <>
      <input
        type="search"
        autoComplete="off"
        autoCorrect="off"
        autoCapitalize="off"
        spellCheck={false}
        maxLength={512}
        onChange={(event) => searchForItems(event.currentTarget.value)}
      />
      <ul>
        {items.map((item) => (
          <li key={item.label}>
            <label>
              <input
                type="checkbox"
                checked={item.isRefined}
                onChange={() => refine(item.value)}
              />
              <span>{item.label}</span>
              <span>({item.count})</span>
            </label>
          </li>
        ))}
      </ul>
      <button onClick={toggleShowMore} disabled={!canToggleShowMore}>
        {isShowingMore ? "Show less" : "Show more"}
      </button>
    </>
  );
}
I