Integrations / Platforms / Shopify / Customizing InstantSearch
Aug. 19, 2019

Customizing InstantSearch

Basic customization options are described in the InstantSearch configuration section.

If you want to customize your search beyond what can be done in the configuration section, you’ll need to modify the files we installed into your theme. This requires a certain level of proficiency in JavaScript and CSS.

If you modify any of the files we added to your theme, then you won’t be able to update to the latest version of our plugin without losing your changes because an upgrade overrides your files.

Resources

After you have installed Algolia in your front-end, we load a number of resources into your theme; they fall into three main categories:

  1. External libraries
  2. Generic assets
  3. Plugin specific assets

External libraries

External libraries are hosted in your shop theme using the Shopify Assets Management.

We are using several libraries to build the search experience we provide for your front-end:

  • polyfill: polyfill.io is a library that adds missing features to old browsers, while imposing no overhead on new ones.
  • lodash v3: Lodash is an utility suite that provides helpful, cross-browser methods to manipulate collections, arrays, and objects.
  • jQuery: jQuery is a library designed to manipulate the DOM more easily. Its methods also provide a great abstraction over features implemented differently between browsers.
  • Hogan.js: Hogan is a templating engine. It has its own section in this documentation.
  • algoliasearch: JavaScript API client for Algolia — needed by autocomplete.js.
  • autocomplete.js: Algolia’s autocompletion library.
  • instantsearch.js: Algolia’s library of widgets that are used to build an InstantSearch page.

In our design, we make use of Font Awesome icons.

Generic assets

We’re installing 5 generic assets in your theme that will be loaded on every page:

File Description
snippets/algolia_money_format.liquid Used to retrieve the currency of your shop
assets/algolia_config.js.liquid Holds your configuration. This file is overwritten on every configuration update in your store, and shouldn’t be edited manually
assets/algolia_init.js.liquid Bootstraps the InstantSearch functionalities for your shop
assets/algolia_helpers.js.liquid Hogan templating logic helpers. See the Hogan helpers section for more details
assets/algolia_translations.js.liquid Contains the string constants used to translate backend results into easily readable strings.

Plugin specific assets

Our styling is split into two CSS files, one for the autocompletion menu and one for the InstantSearch page.

Liquid

All the files we’re installing inside your theme are .liquid templates. The format provides direct access to your Shopify settings and your translations.

To access Liquid variables and helpers, use syntax resembling the following:

1
2
3
4
5
{% if settings.use_logo %}
  {{ 'logo.png' | asset_url | img_tag: shop.name }}
{% else %}
  <span class="no-logo">{{ shop.name }}</span>
{% endif %}

Liquid is only evaluated at page render time because it is a back-end templating engine. Therefore you can’t use Liquid to render dynamically retrieved objects (for example, results returned by Algolia’s realtime search). To render dynamically retrieved objects, we use a library called Hogan.

Hogan

Hogan.js is a front-end templating library.

Hogan uses the mustache syntax. However, because both Liquid and Hogan use curly braces {} as their templating delimiters, we changed Hogan’s templating delimiters to brackets ([]).

Variables

Use [[ abc ]] to render a string. Use [[& abc ]] to render a string that contains HTML: for security reasons, be sure you trust the value!

You can access object attributes with the same syntax: [[ attr.abc ]].

Conditions

Hogan uses the same conditionals as JavaScript:

false, 0, "", null, undefined, [], and NaN resolve to false.

Everything else resolves to true.

Use [[# abc ]]abc is true[[/ abc ]] to check if abc is true. Use [[^ abc ]]abc is false[[/ abc ]] to check if abc is false.

Blocks

Blocks are composed of an open tag and a close tag. They have the same syntax as true conditionals ([[# abc ]]content[[/ abc ]]) and allow you to do two things:

Enter an object

When using a variable name, it will look inside the object first, and go up the object tree if it doesn’t find it.

Example:

Template:

1
2
3
4
5
[[# product]]
  [[title]]
  by
  [[storeName]]
[[/ product]]

Called with:

1
2
3
4
5
6
{
  product: {
    title: 'iPhone'
  },
  storeName: 'Apple'
}

Outputs:

iPhone by Apple

Iterate on a list

You can use blocks to display a list.

  • If the list is composed of objects, each object is directly accessible .
  • If the list is composed of values, use [[ . ]] to access them.
  • As with conditions, you can also use [[^ emptylist ]] content [[/ emptylist ]] to check if the list is empty.
Example:

Template:

1
2
3
4
5
6
7
8
9
10
11
[[# products ]]
  - [[ title ]]
[[/ product ]]
-----
[[# tags ]]
  * [[ . ]]
[[/ tags ]]
-----
[[^ prices ]]
  No price yet
[[/ prices ]]

Called with:

1
2
3
4
5
6
7
8
9
10
11
12
{
  products: [{
    title: 'iPhone'
  }, {
    title: 'LG G5'
  }],
  tags: [
    'Electronics',
    'Phones'
  ],
  prices: []
}

Outputs:

1
2
3
4
5
6
7
- iPhone
- LG G5
-----
* Electronics
* Phones
-----
No price yet

Hogan helpers

Helpers are functions to add a bit of logic to your templates.

They are defined in the assets/algolia_helpers.js.liquid file, and will be available in the Hogan templates (e.g. snippets/algolia_product_autocomplete.hogan.liquid).

The helper functions are Mustache lambdas, so you can call them like a block in your templates:

[[# lambda ]] parameter [[/ lambda]] Your helper functions have one parameter: the text between the lambda tags.

Every Hogan template will have access to all the lambdas you’ve written.

Example

Let’s first define a lambda:

1
2
3
4
5
algolia.helpers = {
  printer: function (text, render) {
    return render(text);
  }
};

Rendering the template:

1
2
3
[[# helpers.printer ]]
  2
[[/ helpers.printer ]]

Called with:

1
2
3
{
  helpers: algolia.helpers
}

Will output: 2.

Advanced example

Adding the lambda:

1
2
3
4
5
6
7
8
algolia.helpers = {
  image_tag: function (text, render) {
    return '<img ' +
        'src="' + render(text) + '" ' +
        'alt="' + this.default_alt + '" ' +
      '/>';
  }
}

Rendering the template:

1
2
3
[[# helpers.image_tag ]]
  [[ image ]]
[[/ helpers.image_tag ]]

Called with:

1
2
3
4
5
{
  image: 'https://www.google.com/images/srpr/logo11w.png',
  default_alt: 'Image',
  helpers: algolia.helpers
}

Outputs: <img src="https://www.google.com/images/srpr/logo11w.png" alt="Image" />

Available helpers

formatNumber

Takes a number as a parameter and returns it formatted in the locale string of the user.

1
2
3
[[# helpers.formatNumber ]]
  2300.43
[[/ helpers.formatNumber ]]

Outputs (depending on your Shopify’s settings):

2,300.43

formattedPrice

Takes a number as a parameter and returns it formatted with currency.

1
2
3
[[# helpers.formattedPrice ]]
  200
[[/ helpers.formattedPrice ]]

Outputs (depending on your Shopify’s settings):

$200

autocompletePrice

Prints the price of an Algolia product (this). If the search uses distinct, show the price range instead.

1
2
[[# autocompletePrice ]]
[[/ autocompletePrice ]]

Example 1: Called with:

1
2
3
4
5
6
7
8
{
  price: 90,
  compare_at_price: 100
  price_ratio: 0.9,
  variants_min_price: 70,
  variants_max_price: 110,
  _distinct: false
}

Outputs:

<b>$90</b>

Example 2: Called with:

1
2
3
4
5
6
7
8
{
  price: 90,
  compare_at_price: 100
  price_ratio: 0.9,
  variants_min_price: 70,
  variants_max_price: 110,
  _distinct: true
}

Outputs:

<b>$70 - $110</b>

instantsearchPrice

Prints the price and its discount of an Algolia product (this). If the search uses distinct, show the price range instead

1
2
[[# instantsearchPrice ]]
[[/ instantsearchPrice ]]

Example 1: Called with:

1
2
3
4
5
6
7
8
{
  price: 90,
  compare_at_price: 100
  price_ratio: 0.9,
  variants_min_price: 70,
  variants_max_price: 110,
  _distinct: true
}

Outputs:

1
2
3
<b>$90</b>
<span class="ais-hit--price-striked">$100</span>
<span class="ais-hit--price-discount" style="font-weight: 100;">-10%</span>';

Example 2: Called with:

1
2
3
4
5
6
7
8
{
  price: 90,
  compare_at_price: 100
  price_ratio: 0.9,
  variants_min_price: 70,
  variants_max_price: 110,
  _distinct: true
}

Outputs: <b>$70 - $110</b>

fullTitle

Prints the title with the variant information of an Algolia product (this).

1
2
[[# fullTitle ]]
[[/ fullTitle ]]

Called with:

1
2
3
4
{
  title: 'iPhone',
  variant_title: '64GB / Gold'
}

Outputs: iPhone (64GB / Gold)

Doesn’t print the variant_title if it equals "Default Title" or "Default"

fullHTMLTitle

Same as fullTitle, but with search highlighting tags included.

floor

Applies Math.floor to the number passed as parameter

Template:

1
2
3
[[# helpers.floor ]]
  2.43
[[/helpers.floor ]]

Outputs: 2

ceil

Applies Math.ceil to the number passed as parameter

Template:

1
2
3
[[# helpers.ceil ]]
  2.43
[[/helpers.ceil ]]

Outputs: 3

Image helpers

Images URLs helper for an Algolia product (this).

You can use the sizedImage helper to specify a size for your image. You can use all the available size options of img_url in liquid. It also works with named sizes.

Template:

1
2
3
4
5
6
7
8
9
[[# sizedImage ]]
  64x32
[[/ sizedImage ]]
[[# sizedImage ]]
  64x
[[/ sizedImage ]]
[[# sizedImage ]]
  pico
[[/ sizedImage ]]

Called with:

1
2
3
{
  image: 'https://i.myshopify.com/abc.png'
}

Outputs:

1
2
3
https://i.myshopify.com/abc_64x32.png
https://i.myshopify.com/abc_64x.png
https://i.myshopify.com/abc_pico.png

For backward compatibility, you can also use named sizes helpers (deprecated by Shopify):

  • picoImage
  • iconImage
  • thumbImage
  • smallImage
  • compactImage
  • mediumImage
  • largeImage
  • grandeImage
  • originalImage

Template:

1
2
[[# picoImage ]]
[[/ picoImage ]]

Called with:

1
2
3
{
  image: 'https://i.myshopify.com/abc.png'
}

Outputs:

https://i.myshopify.com/abc_pico.png

Displaying search results as a list by default

If you want to change the default display to a list style, make the following small change to snippets/algolia_instant_search.hogan.liquid:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- +'s in the margin represent added lines, -'s represent removed lines -->

@@ -24,15 +24,15 @@
     <div class="ais-search-header">
       <div class="ais-stats-container"></div>
       <div class="ais-change-display">
-        <span class="ais-change-display-block ais-change-display-selected"><i class="fa fa-th-large"></i></span>
-        <span class="ais-change-display-list"><i class="fa fa-th-list"></i></span>
+        <span class="ais-change-display-block"><i class="fa fa-th-large"></i></span>
+        <span class="ais-change-display-list ais-change-display-selected"><i class="fa fa-th-list"></i></span>
       </div>
       <div class="ais-sort">
         Sort by
         <span class="ais-sort-orders-container"></span>
       </div>
     </div>
-    <div class="ais-hits-container ais-results-as-block"></div>
+    <div class="ais-hits-container ais-results-as-list"></div>
   </div>
   <div class="ais-pagination-container"></div>
 </div>

Enabling Algolia’s search without as you type experience

To enable Algolia powered search on your Shopify application without the search as you type experience, do the following:

1. From the dashboard, make sure your theme has the Algolia plugin installed. Please make a duplicate version for testing/beta purposes.

2. From the Search Options tab, click the InstantSearch checkbox to enable InstantSearch and hit save.

InstantSearch settings

3. Click on the Open templates/search.liquid button to see the code files.

4. Under Assets category, open the algolia_instant_search.js.liquid file.

5. Find the line containing SearchBox widget and add the following parameter searchOnEnterKeyPressOnly: true, as shown below.

Snippet algolia InstantSearch settings

6. Incorporate InstantSearch into your theme. Note that depending on how you’ve customized your theme, you may need to change some of the styling.

Did you find this page helpful?