Inject Hits from Algolia Rules
Content injection consists of inserting data between search results. With React InstantSearch, you can build a custom widget to mix results from an index and custom content from Algolia Rules into a single set of hits.
This is useful to inject arbitrary content within hits—for example a banner or a video—depending on the search query, filters, or context sent to Algolia. The data would live in individual Algolia Rules, as custom JSON data.
Requirements
React InstantSearch exposes a connector API that lets you reuse existing logic and plug your own. With it, you can build a custom React InstantSearch widget to mix regular Algolia results with injected content. Make sure you’re familiar with this concept before continuing to the next section.
Set up an index and Rule
To find related banners when searching for ingredients, they need to match the same queries.
For example, in your “ingredients” records, you can use a unique name to identify each ingredient. Then, you can use the same name as the Rule pattern.
1
2
3
4
5
6
7
8
[
{
"ingredient": "chicken",
"title": "Chicken",
"summary": "The chicken is a domesticated subspecies of the red junglefowl originally from Southeastern Asia...."
},
// ...
]
Inject custom content between hits
When a Rule that contains custom JSON matches, it’s exposed on the response under the userData
property. You can return it from getHits
to inject it between hits.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import React from 'react';
import {
InstantSearch,
Configure,
Index,
SearchBox,
} from 'react-instantsearch-dom';
import { InjectedHits } from './InjectedHits';
function App() {
return (
<InstantSearch searchClient={searchClient} indexName="ingredients">
<Configure hitsPerPage={8} />
<SearchBox />
<InjectedHits
slots={() => [
{
injectAt: 3,
getHits: ({ resultsByIndex }) => {
const userData = resultsByIndex.products?.userData || [];
const [item] = userData.filter(({ type }) => type === 'banner');
return item ? [item] : [];
},
slotComponent: BannerHit,
},
]}
hitComponent={IngredientHit}
/>
</InstantSearch>
);
}
// ...
When the Rule matches, it will show up at the specified position. Regular hits use the component defined with hitComponent
, while injected hits from Rules use the slotComponent
.
Dynamic positioning with Rules
Instead of passing a static position to injectAt
, you can store a dynamic position in Rules, along with their data, and use it in the code.
If you inject multiple slots at the same position, they’re injected in the defined slot order.
1
2
3
4
5
6
{
"position": 3,
"type": "banner",
"title": "100 Delicious Chicken Recipes",
"image": "chicken.jpg"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import React from 'react';
import {
InstantSearch,
Configure,
Index,
SearchBox,
} from 'react-instantsearch-dom';
import { InjectedHits } from './InjectedHits';
function App() {
return (
<InstantSearch searchClient={searchClient} indexName="ingredients">
<Configure hitsPerPage={8} />
<SearchBox />
<InjectedHits
slots={({ resultsByIndex }) => {
const userData = resultsByIndex.products?.userData || [];
const [item] = userData.filter(({ type }) => type === 'banner');
return [
{
injectAt: item.position,
getHits: () => (item ? [item] : []),
slotComponent: BannerHit,
},
];
}}
hitComponent={IngredientHit}
/>
</InstantSearch>
);
}
// ...