hits
hits({ container: string|HTMLElement, // Optional parameters escapeHTML: boolean, templates: object, cssClasses: object, transformItems: function, });
1
import { hits } from 'instantsearch.js/es/widgets';
About this widget
Use the hits
widget to display a list of search results.
To set the number of search results, use the hitsPerPage
or configure
widget.
Examples
1
2
3
4
5
6
7
8
9
10
11
12
13
hits({
container: '#hits',
templates: {
item(hit, { html, components }) {
return html`
<h2>
${components.Highlight({ attribute: 'name', hit })}
</h2>
<p>${hit.description}</p>
`;
},
},
});
Options
container
|
type: string|HTMLElement
Required
The CSS Selector or |
||
Copy
|
|||
escapeHTML
|
type: boolean
default: true
Optional
Escapes HTML entities from hits string values. |
||
Copy
|
|||
templates
|
type: object
Optional
The templates to use for the widget. |
||
Copy
|
|||
cssClasses
|
type: object
default: {}
Optional
The CSS classes you can override:
|
||
Copy
|
|||
transformItems
|
type: function
default: items => items
Optional
Receives the items 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.
Don’t use The entire If you’re transforming an attribute with the |
||
Copy
|
Templates
You can customize parts of the widget’s UI using the Templates API.
Every template provides an html
function you can use as a tagged template. Using html
lets you safely provide templates as an HTML string. It works directly in the browser without a build step. See Templating your UI for more information.
The html
function is available starting from v4.46.0.
empty
|
type: string|function
Optional
The template to use when there are no results. It exposes the |
||
Copy
|
|||
item
|
type: string|function
Optional
The template to use for each result. This template receives an object containing a single record. The record has a new property |
||
Copy
|
|||
banner
|
type: string|function
Optional
The template to use for the banner. This template receives an object containing the |
||
Copy
|
HTML output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="ais-Hits">
<aside class="ais-Hits-banner">
<a class="ais-Hits-banner-link">
<img class="ais-Hits-banner-image" />
</a>
</aside>
<ol class="ais-Hits-list">
<li class="ais-Hits-item">
...
</li>
<li class="ais-Hits-item">
...
</li>
<li class="ais-Hits-item">
...
</li>
</ol>
</div>
Customize the UI with connectHits
If you want to create your own UI of the hits
widget, you can use connectors.
To use connectHits
, you can import it with the declaration relevant to how you installed InstantSearch.js.
1
import { connectHits } from 'instantsearch.js/es/connectors';
Then it’s a 3-step process:
// 1. Create a render function
const renderHits = (renderOptions, isFirstRender) => {
// Rendering logic
};
// 2. Create the custom widget
const customHits = connectHits(
renderHits
);
// 3. Instantiate
search.addWidgets([
customHits({
// instance params
})
]);
Create a render function
This rendering function is called before the first search (init
lifecycle step)
and each time results come back from Algolia (render
lifecycle step).
const renderHits = (renderOptions, isFirstRender) => {
const {
object[] items,
object results,
object banner,
function sendEvent,
object widgetParams,
} = renderOptions;
if (isFirstRender) {
// Do some initial rendering and bind events
}
// Render the widget
}
Rendering options
items
|
type: object[]
The matched hits from the Algolia API. You can use Algolia’s highlighting feature with the |
||
Copy
|
|||
results
|
type: object
The complete response from the Algolia API. It contains the |
||
Copy
|
|||
banner
|
type: object
The banner data returned within the |
||
Copy
|
|||
sendEvent
|
type: (eventType, hit, eventName) => void
The function to send
Learn more about these events in the |
||
Copy
|
|||
widgetParams
|
type: object
All original widget options forwarded to the render function. |
||
Copy
|
Create and instantiate the custom widget
We first create custom widgets from our rendering function, then we instantiate them. When doing that, there are two types of parameters you can give:
- Instance parameters: they are predefined parameters that you can use to configure the behavior of Algolia.
- Your own parameters: to make the custom widget generic.
Both instance and custom parameters are available in connector.widgetParams
, inside the renderFunction
.
const customHits = connectHits(
renderHits
);
search.addWidgets([
customHits({
// Optional parameters
escapeHTML: boolean,
transformItems: function,
})
]);
Instance options
escapeHTML
|
type: boolean
default: true
Optional
Escapes HTML entities from hits string values. |
||
Copy
|
|||
transformItems
|
type: function
default: items => items
Optional
Receives the items 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.
Don’t use The entire If you’re transforming an attribute with the ‘function’: |
Copy
|
Full example
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
// Create the render function
const renderHits = (renderOptions, isFirstRender) => {
const { items, widgetParams } = renderOptions;
widgetParams.container.innerHTML = `
<ul>
${items
.map(
item =>
`<li>
${instantsearch.highlight({ attribute: 'name', hit: item })}
</li>`
)
.join('')}
</ul>
`;
};
// Create the custom widget
const customHits = connectHits(renderHits);
// Instantiate the custom widget
search.addWidgets([
customHits({
container: document.querySelector('#hits'),
})
]);
Click and conversion events
If the insights
option is true
, the hits
widget automatically sends a click
event with the following shape to the Insights API whenever users click a hit.
1
2
3
4
5
6
7
8
9
{
eventType: 'click',
insightsMethod: 'clickedObjectIDsAfterSearch',
payload: {
eventName: 'Hit Clicked',
// …
},
widgetType: 'ais.hits',
}
To customize this event, use the sendEvent
function in your item
template and send a custom click
event.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
hits({
templates: {
item(hit, { html, components, sendEvent }) {
return html`
<div onClick="${() => sendEvent('click', hit, 'Product Clicked')}">
<h2>
${components.Highlight({ attribute: 'name', hit })}
</h2>
<p>${hit.description}</p>
</div>
`;
},
},
});
The sendEvent
function also accepts an object as a fourth argument to send directly to the Insights API. You can use it, for example, to send special conversion
events with a subtype.
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
36
37
38
hits({
templates: {
item(hit, { html, components, sendEvent }) {
return html`
<div>
<h2>${components.Highlight({ attribute: 'name', hit })}</h2>
<p>${hit.description}</p>
<button
onClick=${() =>
sendEvent('conversion', hit, 'Added To Cart', {
// Special subtype
eventSubtype: 'addToCart',
// An array of objects representing each item added to the cart
objectData: [
{
// The discount value for this item, if applicable
discount: hit.discount || 0,
// The price value for this item (minus the discount)
price: hit.price,
// How many of these items were added
quantity: 2,
// The per-item `queryID` for the query preceding this event
queryID: hit.__queryID,
},
],
// The total value of all items
value: hit.price * 2,
// The currency code
currency: 'USD',
})}
>
Add to cart
</button>
</div>
`;
},
},
});
Fields representing monetary values accept both numbers and strings, in major currency units (for example, 5.45
or '5.45'
).
To prevent floating-point math issues, use strings, especially if you’re performing calculations.