Custom "No Results Found" Page
Introduction
The rcc-search-no-results component lets merchants replace the default empty-state message on Shopify Search Results and Product Grid collection App Blocks with a custom Web Component.
Use this when merchants want to:
- Keep no-results messaging on-brand
- Provide clear next steps for shoppers
- Add a support path such as live chat
Example Component
The example below shows a full no-results custom component. It accepts an activeQuery value, can clear active filters, and includes a support action placeholder.
assets/rcc-search-no-results.js
(function () {
'use strict';
class SearchNoResultsComponent extends HTMLElement {
constructor() {
super();
this._setFilters = null;
this._setQuery = null;
this._clearFilters = null;
this._activeQuery = '';
this._searchSignals = null;
this.attachShadow({ mode: 'open' });
}
set setFilters(fn) {
this._setFilters = fn;
this._render();
}
set setQuery(fn) {
this._setQuery = fn;
this._render();
}
set clearFilters(fn) {
this._clearFilters = fn;
this._render();
}
set activeQuery(val) {
this._activeQuery = val || '';
this._render();
}
get activeQuery() {
return this._activeQuery;
}
set searchSignals(val) {
this._searchSignals = val;
this._render();
}
connectedCallback() {
this._render();
}
_render() {
if (!this.shadowRoot) return;
const style = `
:host { display: block; }
.wrap { padding: 16px; border: 1px solid #d1d5db; border-radius: 8px; }
.title { margin: 0 0 8px; font-weight: 700; }
.text { margin-bottom: 12px; line-height: 1.4; }
.actions { display: flex; gap: 8px; align-items: center; }
button { cursor: pointer; border: 0; background: transparent; color: #325c93; font-weight: 600; }
`;
this.shadowRoot.innerHTML = `
<style>${style}</style>
<div class="wrap" role="region" aria-label="No results">
<div class="title">No Results Found</div>
<div class="text">
No results found for "<b>${this._activeQuery || ''}</b>".<br/><br/>
Search tips:
<ul>
<li>Use fewer keywords</li>
<li>Check spelling</li>
<li>Try using different or broader keywords</li>
</ul>
<div class="actions">
Need help?
<button data-action="clear">
Clear filters
</button>
<button data-action="support">
Contact support
</button>
</div>
</div>
</div>
`;
this.shadowRoot
.querySelector('[data-action="clear"]')
?.addEventListener('click', () => this._clearFilters?.());
this.shadowRoot
.querySelector('[data-action="support"]')
?.addEventListener('click', () => {
// TODO: Hook this up to the chat/support launcher.
});
}
}
customElements.define('rcc-search-no-results', SearchNoResultsComponent);
})();
The App Block assigns these properties when the component renders:
setFilters(filters)replaces the active filter listclearFilters()removes all active filterssetQuery(query)updates the search queryactiveQuerycontains the current search querysearchSignalscontains the current search signal state
When adding this JavaScript file to the theme, include it in theme.liquid before the search or collection App Block renders:
theme.liquid
{%- if request.page_type == 'search' or request.page_type == 'collection' %}
{{ 'rcc-search-no-results.js' | asset_url | script_tag }}
{%- endif %}