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
<RelatedProducts
  objectIDs={string[]}
  // Optional props
  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 { RelatedProducts } from 'react-instantsearch';

About this widget

Use the <RelatedProducts> widget to display a list of related products and related content.

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

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

Examples

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

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

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

function App() {
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <RelatedProducts
        objectIDs={["5723537"]}
        itemComponent={Item}
      />
    </InstantSearch>
  );
}

Display the <RelatedProducts> 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
import React from 'react';
import { liteClient as algoliasearch } from 'algoliasearch/lite';
import { InstantSearch, RelatedProducts, 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}>
      <RelatedProducts
        objectIDs={["5723537"]}
        itemComponent={Item}
        layoutComponent={Carousel}
      />
    </InstantSearch>
  );
}

Props

objectIDs
type: string[]
Required

The list of objectIDs to get recommendations for. If you specify multiple objectIDs, you’ll get a single set of aggregated results from the requests, ordered by their score.

Each objectID you pass in the array counts towards the number of requests in your pricing plan. For example, if you want recommendations for the array ["A", "B", "C"], you’ll consume three requests from your quota, not one.

1
2
3
4
<RelatedProducts
  // ...
  objectIDs={["5723537"]}
/>
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
<RelatedProducts
  // ...
  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
<RelatedProducts
  // ...
  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
<RelatedProducts
  // ...
  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';

<RelatedProducts
  // ...
  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
<RelatedProducts
  // ...
  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
<RelatedProducts
  // ...
  threshold={80}
/>
queryParameters
type: Omit<SearchParameters, "hitsPerPage" | "length" | "offset" | "page">
Optional

List of search parameters to send.

1
2
3
4
5
6
<RelatedProducts
  // ...
  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
<RelatedProducts
  // ...
  fallbackParameters={{
    filters: 'category:Book',
  }}
/>
escapeHTML
type: boolean
default: true
Optional

Whether to escape HTML tags from recommendations string values.

1
2
3
4
<RelatedProducts
  // ...
  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 (
    <RelatedProducts
      // ...
      transformItems={transformItems}
    />
  );
}
classNames
type: Partial<RelatedProductsClassNames>
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
<RelatedProducts
  // ...
  classNames={{
    root: 'MyCustomRelatedProducts',
    list: 'MyCustomRelatedProducts MyCustomRelatedProducts--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
<RelatedProducts
  // ...
  translations={{
    title: 'Associated items'
  }}
/>
...props
type: React.ComponentProps<'div'>
Optional

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

1
2
3
4
5
<RelatedProducts
  // ...
  className="MyCustomRelatedProducts"
  title="My custom title"
/>

Hook

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

The useRelatedProducts() Hook accepts parameters and returns APIs.

Usage

First, create your React component:

import { useRelatedProducts } from 'react-instantsearch';

function CustomRelatedProducts(props) {
  const { items } = useRelatedProducts(props);

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

Then, render the widget:

<CustomRelatedProducts {...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.

objectIDs
type: string[]
Required

The list of objectIDs to get recommendations for. If you specify multiple objectIDs, you’ll get a single set of aggregated results from the requests, ordered by their score.

Each objectID you pass in the array counts towards the number of requests in your pricing plan. For example, if you want recommendations for the array ["A", "B", "C"], you’ll consume three requests from your quota, not one.

1
2
3
4
const { items } = useRelatedProducts({
  // ...
  objectIDs: ['5723537'],
});
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 } = useRelatedProducts({
  // ...
  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 } = useRelatedProducts({
  // ...
  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 } = useRelatedProducts({
  // ...
  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 } = useRelatedProducts({
  // ...
  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 } = useRelatedProducts({
  // ...
  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 RelatedProducts() {
  const relatedProductsApi = useRelatedProducts({
    // ...
    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 { useRelatedProducts } from 'react-instantsearch';

function CustomRelatedProducts(props) {
  const { items } = useRelatedProducts(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?