Predictive Results Section (sections/predictive-results.liquid)
sections/predictive-results.liquid displays search results from Shopify's predictive search API. It renders suggestions, collections, articles, pages, and products in organized sections with proper ARIA attributes for accessibility. The section only renders when a predictive search has been performed.
Dependencies & Assets
| Type | Files / Components |
|---|---|
| CSS | component-predictive-search.css (loaded in theme layout when predictive search is enabled) |
| JavaScript | component-predictive-search.js (loaded in theme layout when predictive search is enabled) |
| Snippets | component-product-price (for product pricing display) |
| Icons | icon-arrow.svg (inline via inline_asset_content) |
| Data | Relies on predictive_search object (resources: queries, collections, articles, pages, products) |
- Section only renders when
predictive_search.performedistrue. - CSS and JavaScript are loaded conditionally in
layout/theme.liquidbased onsettings.predictive_search_enabled. - Product results use the
component-product-pricesnippet for consistent pricing display. - Section respects theme settings:
settings.predictive_search_show_vendorandsettings.predictive_search_show_price.
Markup Structure
{%- if predictive_search.performed -%}
<div id="predictive-search-results">
<div id="predictive-results__wrapper">
<!-- Suggestions (queries and collections) -->
<!-- Articles and Pages -->
<!-- Products -->
</div>
<!-- View all results link -->
</div>
{%- endif -%}- Conditional rendering: Section only displays when predictive search has been performed.
- Container IDs: Uses
id="predictive-search-results"andid="predictive-results__wrapper"for JavaScript targeting. - Accessibility: All lists use proper ARIA roles (
role="listbox",role="option").
Suggestions Section
{%- if predictive_search.resources.queries.size > 0 or predictive_search.resources.collections.size > 0 -%}
<div>
<h3>Suggestions</h3>
<ul role="listbox" aria-labelledby="predictive-search-suggestions">
{%- for query in predictive_search.resources.queries -%}
<li role="option">
<a href="{{ query.url }}" class="predictive-search__item" tabindex="-1">
{{ query.styled_text }}
</a>
</li>
{%- endfor -%}
{%- for collection in predictive_search.resources.collections -%}
<li role="option">
<a href="{{ collection.url }}" class="predictive-search__item" tabindex="-1">
{{ collection.title }}
</a>
</li>
{%- endfor -%}
</ul>
</div>
{%- endif -%}- Query suggestions: Displays styled text from search queries (e.g., "shoes" with matching terms highlighted).
- Collection links: Shows matching collections by title.
- ARIA attributes: Uses
role="listbox"androle="option"for screen reader support. - Tabindex: Links use
tabindex="-1"to allow programmatic focus management by JavaScript.
Articles and Pages Section
{%- if predictive_search.resources.articles.size > 0 or predictive_search.resources.pages.size > 0 -%}
<div>
<h3>Articles and Pages</h3>
<ul role="listbox" aria-labelledby="predictive-search-articles">
{%- for page in predictive_search.resources.pages -%}
<li role="option">
<a href="{{ page.url }}" class="predictive-search__item" tabindex="-1">
{{ page.title | escape }}
</a>
</li>
{%- endfor -%}
{%- for article in predictive_search.resources.articles -%}
<li role="option">
<a href="{{ article.url }}" class="predictive-search__item" tabindex="-1">
{{ article.title | escape }}
</a>
</li>
{%- endfor -%}
</ul>
</div>
{%- endif -%}- Content pages: Displays matching pages and blog articles.
- Title escaping: All titles are escaped for security.
- Consistent structure: Same ARIA pattern as suggestions section.
Products Section
{%- if predictive_search.resources.products.size > 0 -%}
<div class="predictive-search__products">
<h3>Products</h3>
<ul role="listbox" aria-labelledby="predictive-search-products">
{%- for product in predictive_search.resources.products -%}
<li role="option">
<a href="{{ product.url }}">
{%- if product.featured_media != blank -%}
<img
class="predictive-search__image"
src="{{ product.featured_media | image_url: width: 150 }}"
alt="{{ product.featured_media.alt | escape }}"
width="50"
height="{{ 50 | divided_by: product.featured_media.preview_image.aspect_ratio }}"
>
{%- endif -%}
<div class="predictive-search__item-content">
{%- if settings.predictive_search_show_vendor -%}
<small class="predictive-search__item-vendor">
{{ product.vendor }}
</small>
{%- endif -%}
<p class="predictive-search__item-heading">{{ product.title | escape }}</p>
{%- if settings.predictive_search_show_price -%}
{% render 'component-product-price', product: product, use_variant: true, show_badges: false %}
{%- endif -%}
</div>
</a>
</li>
{%- endfor -%}
</ul>
</div>
{%- endif -%}- Product images: Shows featured media at 150px width, displayed at 50px width with calculated height for aspect ratio.
- Vendor display: Conditionally shows vendor based on
settings.predictive_search_show_vendor. - Price display: Uses
component-product-pricesnippet whensettings.predictive_search_show_priceis enabled. - Image aspect ratio: Calculates height dynamically to maintain proper aspect ratio.
View All Results Link
<a href="{{ routes.search_url }}?q={{ predictive_search.terms }}">
<span>Search for "{{ predictive_search.terms }}"</span>
{{- 'icon-arrow.svg' | inline_asset_content -}}
</a>- Full search page: Links to the full search results page with the search query.
- Icon: Uses inline SVG arrow icon for visual indication.
- Query parameter: Passes search terms via
qquery parameter.
Behavior
- Conditional rendering: Section only renders when
predictive_search.performedistrue. - Dynamic content: All content is server-rendered based on predictive search API results.
- Accessibility: Full ARIA support with proper roles and labels for screen readers.
- Keyboard navigation: Links use
tabindex="-1"to allow JavaScript to manage focus programmatically. - Theme settings integration: Respects
settings.predictive_search_show_vendorandsettings.predictive_search_show_pricefor conditional display.
Schema
This section does not include a {% schema %} block, meaning:
- No customizable settings in the theme editor.
- All configuration comes from theme settings (
settings.predictive_search_show_vendor,settings.predictive_search_show_price). - Section is typically rendered via AJAX by the predictive search JavaScript component.
Note: This section is designed to be dynamically loaded into a container (typically #predictive-search) by the component-predictive-search.js custom element.
Implementation Notes
Predictive search integration: This section is loaded via AJAX by the
<predictive-search>custom element when users type in the search input. The JavaScript fetches this section with the search query and renders it into the results container.Translation keys: Section headings ("Suggestions", "Articles and Pages", "Products") are hardcoded and not localized. Consider using translation filters if internationalization is needed.
Image optimization: Product images are requested at 150px width but displayed at 50px, allowing for high-DPI displays while keeping file sizes reasonable.
Aspect ratio calculation: Product image height is calculated using
50 | divided_by: product.featured_media.preview_image.aspect_ratioto maintain proper proportions.Query styled text: Search query suggestions use
query.styled_textwhich includes HTML markup for highlighting matching terms (e.g.,<strong>tags).Collection display: Collections are shown by title only, without images or additional metadata.
Content escaping: All user-generated content (titles, vendor names) are escaped using the
escapefilter for security.Tabindex management: All result links use
tabindex="-1"to allow the predictive search JavaScript to manage keyboard navigation programmatically.ARIA labels: Each list uses
aria-labelledbyto reference the heading (though the IDs are not explicitly set in the headings - this may need adjustment).View all link: The "View all results" link appears at the bottom of all results, providing a clear path to the full search page.
No empty states: The section doesn't render if no results are found (handled by the outer conditional).
CSS class dependencies: Section relies on CSS classes like
predictive-search__item,predictive-search__image,predictive-search__item-content,predictive-search__item-vendor,predictive-search__item-heading, etc. Ensure these are defined incomponent-predictive-search.css.JavaScript integration: The
component-predictive-search.jscustom element handles:- Fetching this section via AJAX
- Managing focus and keyboard navigation
- Showing/hiding the results container
- Debouncing search input
Theme settings: Section respects two theme settings:
settings.predictive_search_show_vendor: Controls vendor display in product resultssettings.predictive_search_show_price: Controls price display in product results
Product price snippet: Uses
component-product-pricewithuse_variant: trueandshow_badges: falsefor consistent pricing display without sale badges.Icon dependency: Requires
icon-arrow.svgin theassets/folder for the "View all results" link.Search terms display: The "View all results" link displays the actual search terms in quotes for clarity.
No pagination: Predictive search results are limited (typically 4-5 items per category) and don't include pagination.