The widgets for displaying recommendations are part of InstantSearch.js,
starting with version 4.69.0.
The Algolia JavaScript API client supports the Recommend API starting with version 4.23.2.
With this, you can integrate recommendations seamlessly into your InstantSearch app,
without having to install additional packages.
Packages
Add the instantsearch.js
and algoliasearch
packages to your project,
and remove the @algolia/recommend
and @algolia/recommend-js
packages:
1
2
3
4
5
| yarn add algoliasearch instantsearch.js
yarn remove @algolia/recommend-js @algolia/recommend
# or
npm install algoliasearch instantsearch.js
npm uninstall @algolia/recommend-js @algolia/recommend
|
Imports
Import the Recommend widgets from InstantSearch.js:
1
2
| - import { frequentlyBoughtTogether } from '@algolia/recommend-js';
+ import { frequentlyBoughtTogether } from 'instantsearch.js/es/widgets';
|
The trendingFacets
function is no longer available.
To replace it, see widgets.
Usage
Add the Recommend widgets to the instantsearch
component.
Pass the API client and index name to the instantsearch
widget:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| - import { frequentlyBoughtTogether } from '@algolia/recommend-js';
+ import instantsearch from 'instantsearch.js';
+ import { frequentlyBoughtTogether } from 'instantsearch.js/es/widgets';
- import recommend from '@algolia/recommend';
+ import algoliasearch from 'algoliasearch/lite';
- const recommendClient = recommend('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const search = instantsearch({
+ searchClient,
+ indexName: 'YOUR_INDEX_NAME',
+ }).addWidgets([
frequentlyBoughtTogether({
container: '#frequentlyBoughtTogether',
- recommendClient,
- indexName: 'YOUR_INDEX_NAME',
objectIDs: ['5723537'],
});
+ ]);
+ search.start();
|
Changes for frequentlyBoughtTogether
Move recommendClient
and indexName
to instantsearch
The frequentlyBoughtTogether
widget no longer needs recommendClient
and indexName
props.
Instead, pass a searchChlient
and the ìndexName
to instantsearch
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| - import { frequentlyBoughtTogether } from '@algolia/recommend-js';
+ import instantsearch from 'instantsearch.js';
+ import { frequentlyBoughtTogether } from 'instantsearch.js/es/widgets';
- import recommend from '@algolia/recommend';
+ import algoliasearch from 'algoliasearch/lite';
- const recommendClient = recommend('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const search = instantsearch({
+ searchClient,
+ indexName: 'YOUR_INDEX_NAME',
+ }).addWidgets([
frequentlyBoughtTogether({
container: '#frequentlyBoughtTogether',
- recommendClient,
- indexName: 'YOUR_INDEX_NAME',
objectIDs: ['5723537'],
});
+ ]);
+ search.start();
|
Replace view
with the connectFrequentlyBoughtTogether
connector
The frequentlyBoughtTogether
widget no longer provides a view
prop.
To fully customize the UI, use the connectFrequentlyBoughtTogether
connector instead.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| - import { frequentlyBoughtTogether } from '@algolia/recommend-js';
+ import {
+ connectFrequentlyBoughtTogether,
+ } from 'instantsearch.js/es/connectors';
+ const customFrequentlyBoughtTogether = connectFrequentlyBoughtTogether(({ items, widgetParams }) => {
+ const container = document.querySelector(widgetParams.container);
+ container.innerHTML = `/* ... */`;
+ });
- frequentlyBoughtTogether({
+ customFrequentlyBoughtTogether({
container: '#frequentlyBoughtTogether',
- view: (props) => { /* ... */ },
}),
|
Replace component props with templates
The frequentlyBoughtTogether
widget uses templates to customize specific parts of its UI.
Recommend JS |
InstantSearch.js |
headerComponent |
header |
itemComponent |
item |
fallbackComponent |
empty |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| frequentlyBoughtTogether({
- headerComponent({ classNames, recommendations, html }) {
- return html`<h2 class=${classNames.title}>
- Recommendations (${recommendations.length})
- </h2>`;
- },
+ templates: {
+ header({ cssClasses, items }, { html }) {
+ return html`<h2 class=${cssClasses.title}>
+ Recommendations (${items.length})
+ </h2>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
9
10
| frequentlyBoughtTogether({
- itemComponent({ item, html }) {
- return html`<p>${item.name}</p>`;
- },
+ templates: {
+ item(recommendation, { html }) {
+ return html`<p>${recommendation.name}</p>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
| frequentlyBoughtTogether({
- fallbackComponent({ html }) {
+ templates: {
+ empty(_, { html }) {
return html`<p>No recommendations.</p>`;
+ }
},
});
|
Replace translations
with templates
The frequentlyBoughtTogether
widget uses templates to provide translations to the header.
1
2
3
4
5
6
7
8
9
10
| frequentlyBoughtTogether({
- translations: {
- title: 'Recommendations',
- },
+ templates: {
+ header: ({ cssClasses }, { html }) {
+ return html`<h2 class=${cssClasses.title}>Recommendations</h2>`;
+ },
+ },
});
|
Replace maxRecommendations
with limit
The limit
prop replaces the maxRecommendations
prop.
1
2
3
4
| frequentlyBoughtTogether({
- maxRecommendations: 3,
+ limit: 3,
});
|
Remove environment
The environment
prop is no longer needed.
1
2
3
| frequentlyBoughtTogether({
- environment: global,
});
|
Replace classNames
with cssClasses
The cssClasses
prop replaces the classNames
prop.
1
2
3
4
5
6
7
8
9
10
11
| frequentlyBoughtTogether({
- classNames: {
+ cssClasses: {
root: 'MyCustomFrequentlyBoughtTogether',
+ emptyRoot: 'MyCustomFrequentlyBoughtTogether-emptyRoot',
title: 'MyCustomFrequentlyBoughtTogether-title',
container: 'MyCustomFrequentlyBoughtTogether-container',
list: 'MyCustomFrequentlyBoughtTogether-list',
item: 'MyCustomFrequentlyBoughtTogether-item',
},
});
|
Move recommendClient
and indexName
to instantsearch
The relatedProducts
widget no longer needs recommendClient
and indexName
props.
Instead, pass a searchChlient
and the ìndexName
to instantsearch
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| - import { relatedProducts } from '@algolia/recommend-js';
+ import instantsearch from 'instantsearch.js';
+ import { relatedProducts } from 'instantsearch.js/es/widgets';
- import recommend from '@algolia/recommend';
+ import algoliasearch from 'algoliasearch/lite';
- const recommendClient = recommend('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const search = instantsearch({
+ searchClient,
+ indexName: 'YOUR_INDEX_NAME',
+ }).addWidgets([
relatedProducts({
container: '#relatedProducts',
- recommendClient,
- indexName: 'YOUR_INDEX_NAME',
objectIDs: ['5723537'],
});
+ ]);
+ search.start();
|
The relatedProducts
widget no longer provides a view
prop.
To fully customize the UI, use the connectRelatedProducts
connector instead.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| - import { relatedProducts } from '@algolia/recommend-js';
+ import {
+ connectRelatedProducts,
+ } from 'instantsearch.js/es/connectors';
+ const customRelatedProducts = connectRelatedProducts(({ items, widgetParams }) => {
+ const container = document.querySelector(widgetParams.container);
+ container.innerHTML = `/* ... */`;
+ });
- relatedProducts({
+ customRelatedProducts({
container: '#relatedProducts',
- view: (props) => { /* ... */ },
}),
|
Replace component props with templates
The relatedProducts
widget uses templates to customize specific parts of its UI.
Recommend JS |
InstantSearch.js |
headerComponent |
header |
itemComponent |
item |
fallbackComponent |
empty |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| relatedProducts({
- headerComponent({ classNames, recommendations, html }) {
- return html`<h2 class=${classNames.title}>
- Recommendations (${recommendations.length})
- </h2>`;
- },
+ templates: {
+ header({ cssClasses, items }, { html }) {
+ return html`<h2 class=${cssClasses.title}>
+ Recommendations (${items.length})
+ </h2>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
9
10
| relatedProducts({
- itemComponent({ item, html }) {
- return html`<p>${item.name}</p>`;
- },
+ templates: {
+ item(recommendation, { html }) {
+ return html`<p>${recommendation.name}</p>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
| relatedProducts({
- fallbackComponent({ html }) {
+ templates: {
+ empty(_, { html }) {
return html`<p>No recommendations.</p>`;
+ }
},
});
|
Replace translations
with templates
The relatedProducts
widget uses templates to provide translations to the header.
1
2
3
4
5
6
7
8
9
10
| relatedProducts({
- translations: {
- title: 'Recommendations',
- },
+ templates: {
+ header: ({ cssClasses }, { html }) {
+ return html`<h2 class=${cssClasses.title}>Recommendations</h2>`;
+ },
+ },
});
|
Replace maxRecommendations
with limit
The limit
prop replaces the maxRecommendations
prop.
1
2
3
4
| relatedProducts({
- maxRecommendations: 3,
+ limit: 3,
});
|
Remove environment
The environment
prop is no longer needed.
1
2
3
| relatedProducts({
- environment: global,
});
|
Replace classNames
with cssClasses
The cssClasses
prop replaces the classNames
prop.
1
2
3
4
5
6
7
8
9
10
11
| relatedProducts({
- classNames: {
+ cssClasses: {
root: 'MyCustomRelatedProducts',
+ emptyRoot: 'MyCustomRelatedProducts-emptyRoot',
title: 'MyCustomRelatedProducts-title',
container: 'MyCustomRelatedProducts-container',
list: 'MyCustomRelatedProducts-list',
item: 'MyCustomRelatedProducts-item',
},
});
|
Changes for trendingItems
Move recommendClient
and indexName
to instantsearch
The trendingItems
widget no longer needs recommendClient
and indexName
props.
Instead, pass a searchClient
and the ìndexName
to instantsearch
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| - import { trendingItems } from '@algolia/recommend-js';
+ import instantsearch from 'instantsearch.js';
+ import { trendingItems } from 'instantsearch.js/es/widgets';
- import recommend from '@algolia/recommend';
+ import algoliasearch from 'algoliasearch/lite';
- const recommendClient = recommend('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const search = instantsearch({
+ searchClient,
+ indexName: 'YOUR_INDEX_NAME',
+ }).addWidgets([
trendingItems({
container: '#trendingItems',
- recommendClient,
- indexName: 'YOUR_INDEX_NAME',
});
+ ]);
+ search.start();
|
Replace view
with the connectTrendingItems()
connector
The trendingItems
widget no longer provides a view
prop.
To fully customize the UI, use the connectTrendingItems
connector instead.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| - import { trendingItems } from '@algolia/recommend-js';
+ import {
+ connectTrendingItems,
+ } from 'instantsearch.js/es/connectors';
+ const customTrendingItems = connectTrendingItems(({ items, widgetParams }) => {
+ const container = document.querySelector(widgetParams.container);
+ container.innerHTML = `/* ... */`;
+ });
- trendingItems({
+ customTrendingItems({
container: '#trendingItems',
- view: (props) => { /* ... */ },
}),
|
Replace component props with templates
The trendingItems
widget uses templates to customize specific parts of its UI.
Recommend JS |
InstantSearch.js |
headerComponent |
header |
itemComponent |
item |
fallbackComponent |
empty |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| trendingItems({
- headerComponent({ classNames, recommendations, html }) {
- return html`<h2 class=${classNames.title}>
- Recommendations (${recommendations.length})
- </h2>`;
- },
+ templates: {
+ header({ cssClasses, items }, { html }) {
+ return html`<h2 class=${cssClasses.title}>
+ Recommendations (${items.length})
+ </h2>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
9
10
| trendingItems({
- itemComponent({ item, html }) {
- return html`<p>${item.name}</p>`;
- },
+ templates: {
+ item(recommendation, { html }) {
+ return html`<p>${recommendation.name}</p>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
| trendingItems({
- fallbackComponent({ html }) {
+ templates: {
+ empty(_, { html }) {
return html`<p>No recommendations.</p>`;
+ }
},
});
|
Replace translations
with templates
The trendingItems
widget uses templates to provide translations to the header.
1
2
3
4
5
6
7
8
9
10
| trendingItems({
- translations: {
- title: 'Recommendations',
- },
+ templates: {
+ header: ({ cssClasses }, { html }) {
+ return html`<h2 class=${cssClasses.title}>Recommendations</h2>`;
+ },
+ },
});
|
Replace maxRecommendations
with limit
The limit
prop replaces the maxRecommendations
prop.
1
2
3
4
| trendingItems({
- maxRecommendations: 3,
+ limit: 3,
});
|
Remove environment
The environment
prop is no longer needed.
1
2
3
| trendingItems({
- environment: global,
});
|
Replace classNames
with cssClasses
The cssClasses
prop replaces the classNames
prop.
1
2
3
4
5
6
7
8
9
10
11
| trendingItems({
- classNames: {
+ cssClasses: {
root: 'MyCustomTrendingItems',
+ emptyRoot: 'MyCustomTrendingItems-emptyRoot',
title: 'MyCustomTrendingItems-title',
container: 'MyCustomTrendingItems-container',
list: 'MyCustomTrendingItems-list',
item: 'MyCustomTrendingItems-item',
},
});
|
Alternative for trendingFacets
InstantSearch.js doesn’t include a widget for trendingFacets
.
If you need it, use the trendingFacets
function
from the deprecated Recommend JS library.
Changes for lookingSimilar
Move recommendClient
and indexName
to instantsearch
The lookingSimilar
widget no longer needs recommendClient
and indexName
props.
Instead, pass a searchChlient
and the ìndexName
to instantsearch
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| - import { lookingSimilar } from '@algolia/recommend-js';
+ import instantsearch from 'instantsearch.js';
+ import { lookingSimilar } from 'instantsearch.js/es/widgets';
- import recommend from '@algolia/recommend';
+ import algoliasearch from 'algoliasearch/lite';
- const recommendClient = recommend('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
+ const search = instantsearch({
+ searchClient,
+ indexName: 'YOUR_INDEX_NAME',
+ }).addWidgets([
lookingSimilar({
container: '#lookingSimilar',
- recommendClient,
- indexName: 'YOUR_INDEX_NAME',
objectIDs: ['5723537'],
});
+ ]);
+ search.start();
|
Replace view
with the connectLookingSimilar()
connector
The lookingSimilar
widget no longer provides a view
prop.
To fully customize the UI, use the connectLookingSimilar
connector instead.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| - import { lookingSimilar } from '@algolia/recommend-js';
+ import {
+ connectLookingSimilar,
+ } from 'instantsearch.js/es/connectors';
+ const customLookingSimilar = connectLookingSimilar(({ items, widgetParams }) => {
+ const container = document.querySelector(widgetParams.container);
+ container.innerHTML = `/* ... */`;
+ });
- lookingSimilar({
+ customLookingSimilar({
container: '#lookingSimilar',
- view: (props) => { /* ... */ },
}),
|
Replace component props with templates
The lookingSimilar
widget uses templates to customize specific parts of its UI.
Recommend JS |
InstantSearch.js |
headerComponent |
header |
itemComponent |
item |
fallbackComponent |
empty |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| lookingSimilar({
- headerComponent({ classNames, recommendations, html }) {
- return html`<h2 class=${classNames.title}>
- Recommendations (${recommendations.length})
- </h2>`;
- },
+ templates: {
+ header({ cssClasses, items }, { html }) {
+ return html`<h2 class=${cssClasses.title}>
+ Recommendations (${items.length})
+ </h2>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
9
10
| lookingSimilar({
- itemComponent({ item, html }) {
- return html`<p>${item.name}</p>`;
- },
+ templates: {
+ item(recommendation, { html }) {
+ return html`<p>${recommendation.name}</p>`;
+ }
+ },
});
|
1
2
3
4
5
6
7
8
| lookingSimilar({
- fallbackComponent({ html }) {
+ templates: {
+ empty(_, { html }) {
return html`<p>No recommendations.</p>`;
+ }
},
});
|
Replace translations
with templates
The lookingSimilar
widget uses templates to provide translations to the header.
1
2
3
4
5
6
7
8
9
10
| lookingSimilar({
- translations: {
- title: 'Recommendations',
- },
+ templates: {
+ header: ({ cssClasses }, { html }) {
+ return html`<h2 class=${cssClasses.title}>Recommendations</h2>`;
+ },
+ },
});
|
Replace maxRecommendations
with limit
The limit
prop replaces the maxRecommendations
prop.
1
2
3
4
| lookingSimilar({
- maxRecommendations: 3,
+ limit: 3,
});
|
Remove environment
The environment
prop is no longer needed.
1
2
3
| lookingSimilar({
- environment: global,
});
|
Replace classNames
with cssClasses
The classNames
keys have changed and are defined through the cssClasses
prop.
1
2
3
4
5
6
7
8
9
10
11
| lookingSimilar({
- classNames: {
+ cssClasses: {
root: 'MyCustomLookingSimilar',
+ emptyRoot: 'MyCustomLookingSimilar-emptyRoot',
title: 'MyCustomLookingSimilar-title',
container: 'MyCustomLookingSimilar-container',
list: 'MyCustomLookingSimilar-list',
item: 'MyCustomLookingSimilar-item',
},
});
|
horizontalSlider
To use a horizontalSlider
component in your Recommend widgets,
use the connectors for the Recommend model, such as connectFrequentlyBoughtTogether()
to customize the widgets.
To customize the item template of the horizontalSlider
in a non-JSX environment,
you can import html
from htm/preact
and use it within the slider’s itemComponent
prop.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| import algoliasearch from 'algoliasearch/lite';
import instantsearch from 'instantsearch.js';
import { customFrequentlyBoughtTogether } from './customFrequentlyBoughtTogether';
const searchClient = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
const search = instantsearch({
searchClient,
indexName: 'YOUR_INDEX_NAME',
}).addWidgets([
customFrequentlyBoughtTogether({
objectIDs: ['5723537'],
}),
]);
search.start();
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| import { html } from 'htm/preact';
import { horizontalSlider } from '@algolia/ui-components-horizontal-slider-js';
import { connectFrequentlyBoughtTogether } from 'instantsearch.js/es/connectors';
import '@algolia/ui-components-horizontal-slider-theme';
export const customFrequentlyBoughtTogether = connectFrequentlyBoughtTogether(({ items, widgetParams }) => {
horizontalSlider({
container: widgetParams.container,
items,
itemComponent: ({ item }) => html`
<article>
<h3>${item.name}</h3>
<p>${item.description}</p>
</article>
`,
})
});
|