A JavaScript module (and Liquid JSON file) that lets you quickly build out search functionality on a Shopify storefront. There is a version of this available as a jQuery plugin, check this branch for more details.
There are plenty of apps on the Shopify App Store, but not many of them are very customizable. This module just takes care of the boilerplate JS and lets you define your own behavior if you like.
Copy ssb.min.js straight into a script tag, or to a file on your site and reference it:
<script src="/path/to/ssb.min.js"></script>
Or install via npm and require (This will only work if you bundle the code and execute on the client; will not run server-side):
npm install shopify-search-bar
require("shopify-search-bar");
- You must make a liquid search template that returns an object with at least a results property that contains an array. Each item in the array must at least have title and url properties. Copy the example into your theme's templates (name it what you like), and customize what kind of info you get about the returned items. Check Shopify's documentation for more about returned items.
- The input element you set as your search bar must be within a form element, and must be of type="text".
Select the input element that will collect the search term, and call the #shopifySearchBar method on it, passing in the urlOpts and containerId args:
var urlOpts = {view: "example", type: "product"};
var containerId = "search-container";
var input = document.getElementById("search-bar");
input.shopifySearchBar(urlOpts, containerId);
- Must have a "view" property. This specifies the Liquid template to query; if this is set to "example", your search will query search.example.liquid, if it is set to "blog", it will query search.blog.liquid, etc.
- Optionally can have a "type" property. This restricts the search to only that type of Shopify object. Options are "page", "product", and "article"".
- Must be the id of the element into which your search will be appended (i.e. a div), without the "#" at the front.
That's all you need to get the default behavior going.
As is, each time a search is performed:
- if there are results, they will be appended into the container in the format:
<p class="ssb-item"> <a href="/path/to/item">Item Title</a> </p>
- if there are no results, this p tag will be appended to the container:
<p class="ssb-failure"> No results were found. </p>
- if something went wrong with the request, this p tag will be appended to the container:
<p class="ssb-failure"> Sorry, something went wrong. </p>
The container will be cleared of all elements before each new request.
Any of these methods can be called on the input element you set as your search bar. You have to initialize the element, as shown above, to use any of these.
Pass in an object with the error messages you want. The object can have properties noResults and searchFailure, which contain the relevant messages to display.
input.messages({noResults: "Sorry, we couldn't find anything!", searchFailure: "Oh no, something's up."});
Pass in a function that will be always called before the request begins. The argument to this function is the results container.
input.before(function (container) {
// do something here
});
Pass in a function that will be always called after the request has ended. The argument to this function is the results container.
input.after(function (container) {
// do something here
});
Pass in a function that will only be called if the result succeeds. The arguments to this function are the results container and the XMLHttpRequest object used.
input.success(function (container, xhr) {
// do something here
});
Pass in a function that will only be called if the result fails. The arguments to this function are the results container and the XMLHttpRequest object used. This overrides the default behavior for a request failure specified above.
input.failure(function (container, xhr) {
// do something here
});
Pass in a function that will be called on each item object in the returned "results" array. The argument to this function is the current item object. This overrides the default behavior for individual item appending specified above.
input.displayItem(function (item) {
// do something here
});
Pass in a function that will be called in the event that there are no search results. The argument to this function is the results container. This overrides the default behavior for a a search with no results specified above.
input.noResults(function (container) {
// do something here
});
Choose whether or not to filter out common stop words from the search query. Set to false by default.
input.cleanQuery(true);
All of the above methods can be called fluidly:
input.before(beforeFn).success(successFn).after(afterFn).cleanQuery(true); // etc