UI libraries / React InstantSearch / Widgets

<FrequentlyBoughtTogether>

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
<FrequentlyBoughtTogether
  objectIDs={string[]}
  // Optional props
  itemComponent={function}
  headerComponent={function}
  emptyComponent={function}
  limit: {number},
  threshold: {number},
  queryParameters: {object},
  escapeHTML={boolean}
  transformItems={function}
  classNames={object}
  translations={object}
  ...props={ComponentProps<'div'>}
/>
Import
1
import { FrequentlyBoughtTogether } from 'react-instantsearch';

About this widget

Use the <FrequentlyBoughtTogether> widget to display a list of frequently bought together items.

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

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

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 algoliasearch from 'algoliasearch/lite';
import { InstantSearch, FrequentlyBoughtTogether } from 'react-instantsearch';

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

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

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

Props

Parameter Description
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
<FrequentlyBoughtTogether
  // ...
  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
<FrequentlyBoughtTogether
  // ...
  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
<FrequentlyBoughtTogether
  // ...
  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
<FrequentlyBoughtTogether
  // ...
  emptyComponent={() => <p>No recommendations.</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
<FrequentlyBoughtTogether
  // ...
  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
<FrequentlyBoughtTogether
  // ...
  threshold={80}
/>
queryParameters
type: Omit<SearchParameters, "hitsPerPage" | "length" | "offset" | "page">
Optional

List of search parameters to send.

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

Whether to escape HTML tags from recommendations string values.

1
2
3
4
<FrequentlyBoughtTogether
  // ...
  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 (
    <FrequentlyBoughtTogether
      // ...
      transformItems={transformItems}
    />
  );
}
classNames
type: Partial<FrequentlyBoughtTogetherClassNames>
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
<FrequentlyBoughtTogether
  // ...
  classNames={{
    root: 'MyCustomFrequentlyBoughtTogether',
    list: 'MyCustomFrequentlyBoughtTogether MyCustomFrequentlyBoughtTogether--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
<FrequentlyBoughtTogether
  // ...
  translations={{
    title: 'Frequently bought with…'
  }}
/>
...props
type: React.ComponentProps<'div'>
Optional

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

1
2
3
4
5
<FrequentlyBoughtTogether
  // ...
  className="MyCustomFrequentlyBoughtTogether"
  title="My custom title"
/>

Hook

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

The useFrequentlyBoughtTogether() Hook accepts parameters and returns APIs.

Usage

First, create your React component:

import { useFrequentlyBoughtTogether } from 'react-instantsearch';

function CustomFrequentlyBoughtTogether(props) {
  const { items } = useFrequentlyBoughtTogether(props);

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

Then, render the widget:

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

Parameter Description
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 } = useFrequentlyBoughtTogether({
  // ...
  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 } = useFrequentlyBoughtTogether({
  // ...
  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 } = useFrequentlyBoughtTogether({
  // ...
  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 } = useFrequentlyBoughtTogether({
  // ...
  queryParameters: {
    filters: 'category:Book',
  },
});
escapeHTML
type: boolean
default: true
Optional

Whether to escape HTML tags from recommendations string values.

1
2
3
4
const { items } = useFrequentlyBoughtTogether({
  // ...
  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 FrequentlyBoughtTogether() {
  const frequentlyBoughtTogetherApi = useFrequentlyBoughtTogether({
    // ...
    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.

Parameter Description
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 { useFrequentlyBoughtTogether } from 'react-instantsearch';

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