🎉 Try the public beta of the new docs site at algolia.com/doc-beta! 🎉
Guides / Building Search UI / Troubleshooting

This is the React InstantSearch v7 documentation. React InstantSearch v7 is the latest version of React InstantSearch and the stable version of React InstantSearch Hooks.

If you were using React InstantSearch v6, you can upgrade to v7.

If you were using React InstantSearch Hooks, you can still use the React InstantSearch v7 documentation, but you should check the upgrade guide for necessary changes.

If you want to keep using React InstantSearch v6, you can find the archived documentation.

It’s recommended to use the Kotlin API client, which is better suited for Android development.

How to use float values in a rating menu widget?

The useRatingMenu() doesn’t support float values. You can store an integer representation of this value in your records (for example, 0.5 * 10 = 5) and display the original value in your UI.

It’s recommended to use the Kotlin API client, which is better suited for Android development.

How to search from the n-th character?

To search only when the query is longer than a certain length, you can implement a proxy search client. Then, you can add a condition, for example, query.length > 3.

It’s recommended to use the Kotlin API client, which is better suited for Android development.

Why is my facet value disappearing from a refinement list after I select it?

A <RefinementList> widget displays the most common values for each facet. Sometimes you might have thousands of different values, and it would be impossible to display them all on the UI. You can make the widget searchable to search for more values based on the user’s query.

Each search query might have different common facet values. What’s visible in the refinement widget depends on which facet values are common for that search query. It can happen that you select a facet value for one search, change the search query, and the selected facet value disappears. It might be a rare facet value for the new search query. The refinement is still active, but it’s not shown in the user interface. This can be confusing.

To also show uncommon facet values, ensure that the maximum number of facet values are returned, by using the <Configure> widget. This gives the widget more data to match its refined values with those returned by Algolia. It has no any incidence on the number of items shown—the boundaries set by limit and showMoreLimit still apply.

1
<Configure maxValuesPerFacet={1000} />

It’s recommended to use the Kotlin API client, which is better suited for Android development.

How do I implement a “Show more” feature on a custom RefinementList?

A custom useRefinementList() widget will show up to showMoreLimit refinement items in items. It lets you sort the items as you want before they’re trimmed. However, it means you need to slice to the desired limit, and keep track of isShowingMore in local state:

1
2
3
4
5
6
7
8
9
10
11
12
13
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`
})

It’s recommended to use the Kotlin API client, which is better suited for Android development.

Why is my searchState ignored?

The uiState works only when the widgets responsible for each UI state attribute is mounted. For instance, a SearchBox widget is necessary to provide a query.

It’s recommended to use the Kotlin API client, which is better suited for Android development.

Why isn’t the cache preventing redundant requests to Algolia?

The JavaScript API client caches redundant searches in memory. This avoid sending unnecessary requests to Algolia, and reuses the data you already fetched. If you notice this behavior isn’t working, you might be recreating the search client over every render.

The cache exists at the client instance level, it isn’t shared across different instances. Make sure you create the search client just once.

A typical error is to instantiate the client inside a React component. This causes the code to run for every render. For example, instead of doing:

1
2
3
4
5
6
7
8
9
10
11
function App() {
  const searchClient = algoliasearch();

  return <InstantSearch searchClient={searchClient} />
}

// or

function App() {
  return <InstantSearch searchClient={algoliasearch()} />
}

Make sure to instantiate the client outside of your component tree, and pass it down by reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const searchClient = algoliasearch();

function App() {
  return <InstantSearch searchClient={searchClient} />
}

// or

function App({ appId, apiKey }) {
  // Useful when you need to update the `appId` and `apiKey` at runtime
  // for example when using Secured API keys
  const searchClient = useMemo(() =>
    algoliasearch(appId, apiKey),
    [appId, apiKey]
  );

  return <InstantSearch searchClient={searchClient} />
}

It’s recommended to use the Kotlin API client, which is better suited for Android development.

Why does dynamic faceting cause an extra request?

When the <DynamicWidgets> receives results, it mounts the chosen widgets for that result. An initial search does two network requests. This is because adding a new widget requires a new network request, to know what the refinements are for a facet.

You can avoid this by forcing all facets to be returned by Algolia, or all facets that you maximally want to display the results of. This can be done by adding facets: ['*'] and maxValuesPerFacet using a <Configure> widget:

1
2
3
4
5
6
7
8
9
10
11
12
<Configure
  facets={['*']}
  // the highest value you could mount in "limit" and "showMoreLimit"
  maxValuesPerFacet={10}
/>
<DynamicWidgets fallbackComponent={Menu}>
  <RefinementList attribute="brand" />
  <HierarchicalMenu attributes={['hierarchical.lvl0', 'hierarchical.lvl1']} />
  <Panel>
    <Menu attribute="category" />
  </Panel>
</DynamicWidgets>

It’s recommended to use the Kotlin API client, which is better suited for Android development.

How to use dynamic widgets with more than 1,000 facets?

Dynamic widgets can show up to 1,000 facets. However, if you do have more than 1,000 facets, here’s how to display the ones with the most results.

  1. Add an applicable_facets facet to every object:
1
2
3
4
5
  {
    "applicable_facets": ["special_type", "color"],
    "special_type": "stretch",
    "color": "blue"
  }
  1. Configure the dynamic widget so it doesn’t ask for all facets. Many of them will be hidden anyway because of the 1,000 facet limit. To do this, set facets to [] (empty).
1
  <DynamicWidgets facets={[]} />
  1. Ensure that applicable_facets is always requested. Such as from a hidden menu:
1
2
3
4
5
6
7
  function VirtualMenu(props) {
    useMenu(props);

    return null;
  }

  <VirtualMenu attribute="applicable_facets" />
  1. use transformItems of dynamicWidgets to use the “applicable_facets” for dynamic widget rendering:
1
2
3
4
5
6
  <DynamicWidgets
    facets={[]}
    transformItems={(_items, { results }) =>
      Object.keys(results._rawResults[0].facets.applicable_facets)
    }
  />

It’s recommended to use the Kotlin API client, which is better suited for Android development.

Why does dynamic faceting request all facets?

When the <DynamicWidgets> receives results, it mounts the chosen widgets for that result. To avoid doing an extra network request, facets is set to ['*'] by default.

If you prefer to do two network requests with only the relevant facets returned, you can set facets to [] like this:

1
2
3
4
5
6
7
<DynamicWidgets fallbackComponent={Menu} facets={[]}>
  <RefinementList attribute="brand" />
  <HierarchicalMenu attributes={['hierarchical.lvl0', 'hierarchical.lvl1']} />
  <Panel>
    <Menu attribute="category" />
  </Panel>
</DynamicWidgets>

More detail on these approaches can be found in the facet display guide.

It’s recommended to use the Kotlin API client, which is better suited for Android development.

Does React InstantSearch support TypeScript?

The following packages ship with TypeScript types.

  • react-instantsearch (v7)
  • react-instantsearch-core (v7)

The following packages don’t ship with TypeScript types, but have DefinitelyTyped definitions you can use.

  • react-instantsearch (v6)
  • react-instantsearch-core (v6)
  • react-instantsearch-dom (v6)
  • react-instantsearch-native (v6)

Note that these definitions are maintained by the DefinitelyTyped community. If you experiences issues while using them, please reach out or contribute on DefinitelyTyped.

The following package doesn’t ship with TypeScript types. It has no DefinitelyTyped definitions you can use.

  • react-instantsearch-dom-maps
Did you find this page helpful?