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 list
  • clearFilters() removes all active filters
  • setQuery(query) updates the search query
  • activeQuery contains the current search query
  • searchSignals contains 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 %}