Merchandising Collections?

So Im using instantsearch.js to build collection pages for a Shopify store and the client needs the ability to merchandise them. Query Rules would definitely do the trick, but how can I programmatically trigger query rules per collection?

Currently, we have javascript reading the collection handle from the html (provided by by liquid) and passing it to instantsearch.js like so:

    // other search parameters
    filters: `collections:${handle}`

Hi @darren-segal - We also received your direct email but posting here as well to make sure the community can benefit from the response:

As query rules are triggered by the “query” itself, you would have to make sure this filter value is part of the query.

An approach you can try is to leverage the searchFunction hook of InstantSearch which gets an instance of the helper.js library as a parameter. You can use helper.js to add the value to the query. You can then trigger a search with your new query. Generally this could look like:

const search = instantsearch({
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_KEY',
  indexName: 'YOUR_INDEX_NAME',
  searchParameters: {
    filters: 'collections:'fall-2018'',
  searchFunction: function(helper) {
    if (helper.state.filters && helper.state.filters.includes('fall-2018')) {
      var toAdd = 'fall-2018';
      var oldQuery = helper.state.query;
      var newQuery = oldQuery + ' ' + toAdd;

    } else {;

You will also have to create the query rule triggered by fall-2018 to complete this.

Here is a codesandbox showing this general pattern of checking a filter and setting a new query, as applied to our Algolia sample products index.

Thanks alot @ajay.david, didnt mean to spam you but I received good feedback on the forums so I figured id try both. Ill just post in one spot moving forward.

Interestingly enough we internally discussed potentially adding the collection name to handle into the query, so your solution makes sense to me. The only concern I had was if adding the handle as a query string on top of the collection filter would possibly change the results.

Also, how would adding the query to the base instantsearch instance as

searchParameters: {
    query: 'fall-2018',
    filters: "collections:'fall-2018'"

be different from using the searchFunction hook? Obviously the hook gets called every time, including filtering but doesnt the query come along for the ride if you add it to searchParameters at the start?

Thanks for the help!

Hi @darren-segal,

As the “merchandising” tab in the plugin was built to promote a product and not a page (e.g., collection page), we are getting into features that were not designed out-of-the-box.

I want to take a step back and better understand what you are trying to achieve from a business/UX perspective.

Do you have a live website where maybe part of this is working? Could you describe what you want to happen using this live example?


Sorry if I was being confusing, but we are trying to merchandise products - we have no functionality regarding search for collections/pages. We’re tying to mirror the functionality of a Shopify collection (similarly to how the Algolia Shopify plugin can replace your collection pages with an instant search instance) page but leveraging Query Rules to manually merchandise products. My reply was asking about the difference between you’re searchFunction approach and simply adding the query to searchParameters.query.

After some testing it appears that your code using the searchFunction does not play nicely with some of the instantsearch.js connectors/widgets. For example, it breaks our showMore button (using a connector).

Adding the query to searchParameters seems to work consistently.

There’s one big issue we’re still having, and that is promoting the products causes duplicates, regardless of Distinct settings.

Meaning, if a search would have returned a product anyway, but that product was also promoted to the top, that product will be in the results twice. As a work around, I have done some JS array filtering to deduplicate entries in the hits array based on product handle. But now this is screwing up the number of results returned. If I ask for 15 results per page, but 2 of them were duplicates, I really have 14.

As you might imagine, this could spiral if not kept track of.

Is there anything to do about these issues? Its pretty unfortunate that theres no true way to merchandise collections with Algolia.

Here’s another post I found from a user with seemingly the same issue.

I have spent some time looking into this with some help from support, we did come up with a semi-workable solution that would deduplicate in the browser before the results loaded but I could not get it to work reliably if the user landed on a page other than the one with the promoted products (it would filter the promoted products rather than the non promoted duplicates and pagination was a bit hit and miss).

The best solution I have found is to add all of the products that are variants and not promoted as hidden results (see the image with Cardillo Green Tea below) but obviously, this is a manual and time-consuming process.

I believe that this could be automated by using the Algolia API but for Shopify users, this would mean another add-on to manage & merchandise specifically.

I have asked the question via my ongoing email support thread if this is something that could be feasibly added to Algolia’s own Shopify plugin or if there is a better easier solution i’m not aware of and I will post the response or I invite @ajay.david to jump in if appropriate?