Conditional Display in InstantSearch.js
Handling no results
Not all queries lead to results, and it’s important to let users know when this happens. This gives you an opportunity to provide hints on how to adjust the query. This way, you can ensure users don’t leave your website or search using an external search engine.
Display a message
The easiest way to display a fallback message when a query doesn’t return results is to use the templates.empty
option.
1
2
3
4
5
6
7
8
search.addWidgets([
instantsearch.widgets.hits({
container: 'hits',
templates: {
empty: '<div>No results have been found for {{ query }}</div>.'
}
})
]);
Note that the above example also works with infiniteHits
.
Let the user clear all filters
Users make mistakes, which can cause them to not find any results. You can account for this by providing a way to clear filters right from the “no results” state, so they can start over.
For this purpose, we provide a specific widget called clearRefinements
. However, you can’t use it inside the empty
template, so in this case you need to leverage the routing instead.
First, you need to activate the URL sync mechanism, so that you can easily clear the filters using the URL.
1
2
3
const search = instantsearch({
routing: true
});
Check out the complete routing guide if you want to learn more.
The routing makes your InstantSearch.js app aware of changes in the URL. This lets you influence the parameters of the search, and therefore clear filters by removing URL parameters.
1
2
3
4
5
6
7
8
9
10
11
search.addWidgets([
instantsearch.widgets.hits({
container: 'hits',
templates: {
empty: `<div>
<p>No results have been found for {{ query }}</p>
<a role="button" href=".">Clear all filters</a>
</div>`
}
})
]);
Handling empty queries
By default, InstantSearch.js always shows you results, even when the query is empty. Depending on your use case and the way you want to build your UI, you may want to only show results when there’s a query.
Using the helper state
This hides the results container when the query is empty.
1
2
3
4
5
6
7
8
const search = instantsearch({
searchFunction(helper) {
const container = document.querySelector('#results');
container.style.display = helper.state.query === '' ? 'none' : '';
helper.search();
}
});
Using a connector
This uses the connectHits
connector.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const customHits = instantsearch.connectors.connectHits(
(renderOptions, isFirstRender) => {
const { results, widgetParams } = renderOptions;
const { container } = widgetParams;
container.innerHTML =
results && results.query
? `<div>Searching for query "${results.query}".</div>`
: `<div>No query</div>`;
}
);
search.addWidgets([
customHits({
container: document.querySelector('#hits')
})
]);
Handling errors
When an error occurs, you might want to display a specific piece of content to help the user go back to a normal state.
Making an error-handling widget
You can build a custom widget to handle errors when they occur. If you want to learn more about custom widgets, check out the guide.
1
2
3
4
5
6
7
8
9
search.addWidgets([
{
init({ helper }) {
helper.on('error', error => {
console.error('Error', error);
});
}
}
]);
You can improve this custom widget by writing a more meaningful error message, adapting it to your UI, figuring out whether the user is online or not, and log the error in your monitoring system.