UI libraries / React InstantSearch / Widgets

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.

Signature
<TrendingItems
  // Optional props
  facetName={string}
  facetValue={string}
  itemComponent={function}
  headerComponent={function}
  emptyComponent={function}
  limit: {number},
  threshold: {number},
  queryParameters: {object},
  fallbackParameters: {object},
  escapeHTML={boolean}
  transformItems={function}
  classNames={object}
  translations={object}
  ...props={ComponentProps<'div'>}
/>
Import
1
import { TrendingItems } from 'react-instantsearch';

About this widget

Use the <TrendingItems> widget to display a list of trending items.

If you’re using the deprecated recommend-react UI library, please refer to the API reference for the <TrendingItems> component or useTrendingItems() Hook.

You can also create your own UI with useTrendingItems().

Examples

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from 'react';
import { liteClient as algoliasearch } from 'algoliasearch/lite';
import { InstantSearch, TrendingItems } from 'react-instantsearch';

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

function Item({ item }) {
  return JSON.stringify(item);
}

function App() {
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <TrendingItems
        facetName="category"
        facetValue="Book"
        itemComponent={Item}
      />
    </InstantSearch>
  );
}

Display the <TrendingItems> widget as a scrollable carousel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React from 'react';
import { liteClient as algoliasearch } from 'algoliasearch/lite';
import { InstantSearch, TrendingItems, Carousel } from 'react-instantsearch';

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

function Item({ item }) {
  return JSON.stringify(item);
}

function App() {
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <TrendingItems
        facetName="category"
        facetValue="Book"
        itemComponent={Item}
        layoutComponent={Carousel}
      />
    </InstantSearch>
  );
}

Props

facetName
type: string
Optional

The facet attribute to get recommendations for. This parameter should be used along with facetValue.

1
2
3
4
5
<TrendingItems
  // ...
  facetName="category"
  facetValue="Book"
/>
facetValue
type: string
Optional

The value for the targeted facet name. This parameter should be used along with facetName.

1
2
3
4
5
<TrendingItems
  // ...
  facetName="category"
  facetValue="Book"
/>
itemComponent
type: (props: { item: THit }) => JSX.Element
Optional

A component that renders each recommendation from the results. It receives an item prop.

When not provided, the widget displays the recommendation as a JSON string.

1
2
3
4
<TrendingItems
  // ...
  itemComponent={({ item }) => item.objectID}
/>
headerComponent
type: (props: { classNames: string[], items: THit[], translations: object }) => JSX.Element
Optional

A component that renders a title header. It receives classNames, items and translations props.

When not provided, the widget displays a default header.

1
2
3
4
5
6
7
8
<TrendingItems
  // ...
  headerComponent={({ classNames, items }) => (
    <h2 className={classNames.title}>
      Recommendations ({items.length})
    </h2>
  )}
/>
emptyComponent
type: () => JSX.Element
Optional

A component that renders when there are no recommendations.

When not provided, the widget displays a default message.

1
2
3
4
<TrendingItems
  // ...
  emptyComponent={() => <p>No recommendations.</p>}
/>
layoutComponent
since: v7.13.0
type: (props: RecommendLayoutProps) => JSX.Element
Optional

The layout component to use to wrap all items.

React InstantSearch provides a provides a built-in <Carousel> layout component with the following props:

classNames:

  • root: the Carousel’s root element.
  • list: the list of recommendations.
  • item: the list item.
  • navigation: the navigation controls.
  • navigationPrevious: the “Previous” navigation control.
  • navigationNext: the “Next” navigation control.

translations:

  • nextButtonLabel: the label for the next button.
  • nextButtonTitle: the title for the next button.
  • previousButtonLabel: the label for the previous button.
  • previousButtonTitle: the title for the previous button.
  • listLabel: the label for the list of recommendation.

previousIconComponent: the component to render as the previous button.

nextIconComponent: the component to render as the next button.

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Carousel } from 'react-instantsearch';

<TrendingItems
  // ...
  layoutComponent={(props) => (
    <Carousel
      {...props}
      classNames={{ root: 'MyRootClass' }}
      previousIconComponent={() => <p>Previous</p>}
      nextIconComponent={() => <p>Next</p>}
    />
  )}
/>
limit
type: number
Optional

The number of recommendations to retrieve. Depending on the available recommendations and the other request parameters, the actual number of items may be lower than that. If limit isn’t provided or set to 0, all matching recommendations are returned.

1
2
3
4
<TrendingItems
  // ...
  limit={4}
/>
threshold
type: number
Optional

The threshold for the recommendations confidence score (between 0 and 100). Only recommendations with a greater score are returned.

1
2
3
4
<TrendingItems
  // ...
  threshold={80}
/>
queryParameters
type: Omit<SearchParameters, "hitsPerPage" | "length" | "offset" | "page">
Optional

List of search parameters to send.

1
2
3
4
5
6
<TrendingItems
  // ...
  queryParameters={{
    filters: 'category:Book',
  }}
/>
fallbackParameters
type: Omit<SearchParameters, "hitsPerPage" | "length" | "offset" | "page">
Optional

List of search parameters to send as additional filters when there aren’t enough recommendations.

1
2
3
4
5
6
<TrendingItems
  // ...
  fallbackParameters={{
    filters: 'category:Book',
  }}
/>
escapeHTML
type: boolean
default: true
Optional

Whether to escape HTML tags from recommendations string values.

1
2
3
4
<TrendingItems
  // ...
  escapeHTML={false}
/>
transformItems
type: (items: THit[], metadata: { results: SearchResults }) => THit[]
Optional

Receives the recommendations and is called before displaying them. It returns a new array with the same “shape” as the original. This is helpful when transforming or reordering items.

The entire results data is also available, including all regular response parameters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const transformItems = (items) => {
  return items.map((item) => ({
    ...item,
    label: item.name.toUpperCase(),
  }));
};

function Search() {
  return (
    <TrendingItems
      // ...
      transformItems={transformItems}
    />
  );
}
classNames
type: Partial<TrendingItemsClassNames>
Optional

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 widget’s root element.
  • emptyRoot: the root element without results.
  • title: the widget’s title element.
  • container: the container of the list element.
  • list: the list of recommendations.
  • item: the list item.
1
2
3
4
5
6
7
<TrendingItems
  // ...
  classNames={{
    root: 'MyCustomTrendingItems',
    list: 'MyCustomTrendingItems MyCustomTrendingItems--subclass',
  }}
/>
translations
type: Partial<RecommendTranslations>
Optional

A mapping of keys to translation values.

  • title: The title of the recommendation section.
  • sliderLabel: The label of the horizontal slider.
1
2
3
4
5
6
<TrendingItems
  // ...
  translations={{
    title: 'Trending Books'
  }}
/>
...props
type: React.ComponentProps<'div'>
Optional

Any <div> prop to forward to the widget’s root element.

1
2
3
4
5
<TrendingItems
  // ...
  className="MyCustomTrendingItems"
  title="My custom title"
/>

Hook

React InstantSearch let you create your own UI for the <TrendingItems> widget with useTrendingItems(). Hooks provide APIs to access the widget state and interact with InstantSearch.

The useTrendingItems() Hook accepts parameters and returns APIs.

Usage

First, create your React component:

import { useTrendingItems } from 'react-instantsearch';

function CustomTrendingItems(props) {
  const { items } = useTrendingItems(props);

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

Then, render the widget:

<CustomTrendingItems {...props} />

Parameters

Hooks accept parameters. You can pass them manually, or forward the props from your custom component.

When you provide a function to Hooks, make sure to pass a stable reference to avoid rendering endlessly (for example, with useCallback()). Objects and arrays are memoized; you don’t need to stabilize them.

facetName
type: string
Optional

The facet attribute to get recommendations for. This parameter should be used along with facetValue.

1
2
3
4
5
const { items } = useTrendingItems({
  // ...
  facetName: 'category',
  facetValue: 'Book',
});
facetValue
type: string
Optional

The value for the targeted facet name. This parameter should be used along with facetName.

1
2
3
4
5
const { items } = useTrendingItems({
  // ...
  facetName: 'category',
  facetValue: 'Book',
});
limit
type: number
Optional

The number of recommendations to retrieve. Depending on the available recommendations and the other request parameters, the actual number of items may be lower than that. If limit isn’t provided or set to 0, all matching recommendations are returned.

1
2
3
4
const { items } = useTrendingItems({
  // ...
  limit: 4,
});
threshold
type: number
Optional

The threshold for the recommendations confidence score (between 0 and 100). Only recommendations with a greater score are returned.

1
2
3
4
const { items } = useTrendingItems({
  // ...
  threshold: 80,
});
queryParameters
type: Omit<SearchParameters, "hitsPerPage" | "length" | "offset" | "page">
Optional

List of search parameters to send.

1
2
3
4
5
6
const { items } = useTrendingItems({
  // ...
  queryParameters: {
    filters: 'category:Book',
  },
});
fallbackParameters
type: Omit<SearchParameters, "hitsPerPage" | "length" | "offset" | "page">
Optional

List of search parameters to send as additional filters when there aren’t enough recommendations.

1
2
3
4
5
6
const { items } = useTrendingItems({
  // ...
  fallbackParameters: {
    filters: 'category:Book',
  },
});
escapeHTML
type: boolean
default: true
Optional

Whether to escape HTML tags from recommendations string values.

1
2
3
4
const { items } = useTrendingItems({
  // ...
  escapeHTML: false,
});
transformItems
type: (items: THit[], metadata: { results: SearchResults }) => THit[]
Optional

Receives the recommendations and is called before displaying them. It returns a new array with the same “shape” as the original. This is helpful when transforming or reordering items.

The entire results data is also available, including all regular response parameters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const transformItems = (items) => {
  return items.map((item) => ({
    ...item,
    label: item.name.toUpperCase(),
  }));
};

function TrendingItems() {
  const trendingItemsApi = useTrendingItems({
    // ...
    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
type: THit[]

The matched recommendations returned from Algolia.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React from 'react';
import { useTrendingItems } from 'react-instantsearch';

function CustomTrendingItems(props) {
  const { items } = useTrendingItems(props);

  return (
    <ol>
      {items.map((item) => (
        <li key={item.objectID}>
          <div style={{ wordBreak: 'break-all' }}>
            {JSON.stringify(item).slice(0, 100)}
          </div>
        </li>
      ))}
    </ol>
  );
}
Did you find this page helpful?