Custom hook events
From December 31, 2023, Algolia’s Search and Discovery application can’t modify the coding of Shopify themes. For more information, refer to Shopify’s Asset API documentation. As an alternative, Algolia offers Shopify’s App Embed and App Blocks features for Autocomplete and InstantSearch interfaces. For more information, refer to the Quick start and Shopify Algolia configuration documentation.
How hooks works
Adjust the logic of the Autocomplete and InstantSearch integration by registering a custom method in your JavaScript file.
The extension provides hooks to help you add or change parameters for the implementation.
The algoliaShopify
window variable is an object that handles the setting and firing of events in the Autocomplete and InstantSearch frontend implementation.
To view the available events, visit your Shopify store and type algoliaShopify.hooks.allowedHooks
into your browser’s API console:
Customizing
Five kinds of hooks are available. Each hook requires a different return value.
Options
expects an objectTemplates
expects a Tagged Template Literal wrapped around html.- example: html`<h1>Algolia</h1>`
Array
expects an array of objects or stringsString
expects a stringNumber
expects a numberAction
expects a function
Autocomplete hooks
beforeAutocompleteOptions(options)
- Used to modify parameter options of the Autocomplete menu
beforeAutocompleteFiltersString(defaultFilter)
- Used to modify the filter parameter of the Autocomplete menu
beforeAutocompleteRedirectUrlOptions(options)
- Used to modify the default parameter options of the
createRedirectUrlPlugin
- the hook must return an
options
value
- Used to modify the default parameter options of the
beforeAutocompleteMainTemplate(defaultTemplate, templateOptions, elements, displaySuggestions)
- Used to modify the HTML template that renders the Autocomplete panel.
- Renders an Autocomplete multi-panel layout
- The
element
object contains the following properties:querySuggestionsPlugin
collections
articles
pages
redirectUrlPlugin
products
beforeAutocompleteMainProductsTemplate(defaultTemplate, templateOptions, elements)
- Renders the Autocomplete menu’s product section
beforeAutocompleteNoResultsTemplate(defaultTemplate, templateOptions)
- Renders a no results section when there are no hits
beforeAutocompleteHeaderTemplate(defaultTemplate, templateOptions, resource)
- Renders a header section at the top of the Autocomplete panel
beforeAutocompleteFooterTemplate(defaultTemplate, templateOptions)
- The ‘Show See All products’ checkbox in the Shopify Algolia Dashboard must be enabled
- Renders a footer section at the bottom of the Autocomplete panel
beforeAutocompleteProductTemplate(defaultTemplate, templateOptions, distinct, itemLink)
- Renders the Autocomplete menu’s product section
beforeAutocompleteArticlesTemplate(defaultTemplate, templateOptions, itemLink)
- Renders the Autocomplete menu’s articles section
beforeAutocompleteCollectionsTemplate(defaultTemplate, templateOptions, itemLink)
- Renders the Autocomplete menu’s collections section
beforeAutocompletePagesTemplate(defaultTemplate, templateOptions, itemLink)
- Renders the Autocomplete menu’s pages section
beforeAutocompleteSuggestionsTemplate(defaultTemplate, templateOptions)
- Renders the Autocomplete menu’s suggestions section
afterAutocompleteProductClickAction(undefined, line_item)
- Used to execute a function after a product is clicked
Examples of Autocomplete hooks
Example of beforeAutocompleteOptions(options)
hook:
1
2
3
4
5
6
7
8
9
// Modify default `options`
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteOptions', function(options) {
// Modify default options, then return them
options.placeholder = "Search Our Products";
return options;
});
});
Example of beforeAutocompleteFiltersString(defaultFilter)
hook:
1
2
3
4
5
6
7
// Omit `_defaultFilter` and return a custom filter
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteFiltersString', function(_defaultFilter) {
// Modify or replace the default string, then return a string
return 'price > 17';
});
});
Example of beforeAutocompleteMainTemplate(defaultTemplate, templateOptions, elements, displaySuggestions)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteMainTemplate', function(_defaultTemplate, templateOptions, elements, displaySuggestions) {
const { html } = templateOptions;
return html`
<div class="aa-PanelLayout aa-Panel--scrollable">
<div class="aa-PanelSections">
<div class="aa-PanelSection--left">
${displaySuggestions &&
html`
<div class="aa-SourceHeader">
<span class="aa-SourceHeaderTitle"
>${algoliaShopify.translations.suggestions}</span
>
<div class="aa-SourceHeaderLine" />
</div>
${elements.querySuggestionsPlugin}
`}
${elements.collections} ${elements.articles} ${elements.pages}
${elements.redirectUrlPlugin}
</div>
<div class="aa-PanelSection--right">
${elements.products}
</div>
</div>
</div>
`;
});
});
Example of beforeAutocompleteMainProductsTemplate(defaultTemplate, templateOptions, elements)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteMainProductsTemplate', function(_defaultTemplate, templateOptions, elements) {
const { html } = templateOptions;
return html`
<div class="aa-PanelLayout aa-Panel--scrollable">
<div class="aa-PanelSection">
${elements.products}
</div>
</div>
`;
});
});
Example of beforeAutocompleteNoResultsTemplate(defaultTemplate, templateOptions)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteNoResultsTemplate', function(_defaultTemplate, templateOptions) {
const { html, state } = templateOptions;
return html`
<div class="aa-PanelLayout aa-Panel--scrollable">
<p class="aa-NoResultsHeader">
${algoliaShopify.translation_helpers.no_result_for(state.query)}
</p>
<a class="aa-NoResultsLink" href="${window.Shopify.routes.root}search?q=">
${algoliaShopify.translations.allProducts}
</a>
</div>
`;
});
});
Example of beforeAutocompleteHeaderTemplate(defaultTemplate, templateOptions, resource)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteHeaderTemplate', function(_defaultTemplate, templateOptions, resource) {
const { html, state } = templateOptions;
return html`
<div class="aa-SourceHeader">
<span class="aa-SourceHeaderTitle">
${algoliaShopify.translation_helpers.render_title(
resource,
state.query
)}
</span>
<div class="aa-SourceHeaderLine" />
</div>
`;
});
});
Example of beforeAutocompleteFooterTemplate(defaultTemplate, templateOptions)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteFooterTemplate', function(_defaultTemplate, templateOptions) {
const { html, state } = templateOptions;
return html`
<div class="aa-footer">
<a
class="aa-SeeAllBtn"
href="${window.Shopify.routes.root}search?q=${state.query}"
>
${algoliaShopify.translations.allProducts}
(${algoliaShopify.helpers.formatNumber(state.context.nbProducts)})
</a>
</div>
`;
});
});
Example of beforeAutocompleteProductTemplate(defaultTemplate, templateOptions, distinct, itemLink)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
const handleItemClick = (e, line_item) => {
const afterClick = new Event("algoliaShopify.autocomplete.hitClickAction");
document.dispatchEvent(afterClick);
if (algoliaShopify.config.analytics_enabled) {
const clickData = {
index: line_item.__autocomplete_indexName,
eventName: "Added to cart",
queryID: line_item.__autocomplete_queryID,
objectIDs: [line_item.objectID],
};
algoliaShopify.saveForConversionTracking(clickData);
}
const customerCustomAction = algoliaShopify.hooks.triggerHooks(
"afterAutocompleteProductClickAction",
undefined,
line_item
);
if (typeof customerCustomAction === "function") {
customerCustomAction();
}
};
document.addEventListener("algolia.hooks.initialize", function () {
algoliaShopify.hooks.registerHook(
"beforeAutocompleteProductTemplate",
function (_defaultTemplate, templateOptions, distinct, itemLink) {
// Modify default options, then return them
const { html, item, components } = templateOptions;
return html`
<a
href="${itemLink}"
class="aa-ItemLink aa-ProductItem"
onClick="${(event) => handleItemClick(event, item)}"
>
<div class="aa-ItemContent">
<div class="aa-ItemPicture aa-ItemPicture--loaded">
<img
src="${algoliaShopify.helpers.compactImage(item)}"
alt="${item.title}"
/>
</div>
<div class="aa-ItemContentBody">
<div class="aa-ItemContentBrand">
${
item.product_type &&
components.Highlight({ hit: item, attribute: "product_type" })
}
removing vendor
</div>
<div class="aa-ItemContentTitleWrapper">
<div class="aa-ItemContentTitle">
${components.Highlight({ hit: item, attribute: "title" })}
<span class="algolia-variant">
${algoliaShopify.helpers.variantTitleAddition(item, distinct)}
</span>
</div>
</div>
<div class="aa-ItemContentPrice">
<div class="aa-ItemContentPriceCurrent">
${algoliaShopify.helpers.displayPrice(item, distinct)}
</div>
</div>
</div>
</div>
</a>
`;
}
);
});
Example of beforeAutocompleteArticlesTemplate(_defaultTemplate, templateOptions, itemLink)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteArticlesTemplate', function(_defaultTemplate, templateOptions, itemLink) {
const { html, item, components } = templateOptions;
return html`
<a href="${itemLink}" class="aa-ItemLink">
<div class="aa-ItemWrapper">
<div class="aa-ItemContent">
<div class="aa-ItemIcon aa-ItemIcon--noBorder">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"
/>
</svg>
</div>
<div class="aa-ItemContentBody">
<div class="aa-ItemContentTitle">
${components.Highlight({ hit: item, attribute: 'title' })}
</div>
</div>
</div>
</div>
</a>
`;
});
});
Example of beforeAutocompleteCollectionsTemplate(_defaultTemplate, templateOptions, itemLink)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteCollectionsTemplate', function(_defaultTemplate, templateOptions, itemLink) {
const { html, item, components } = templateOptions;
return html`
<a href="${itemLink}" class="aa-ItemLink">
<div class="aa-ItemWrapper">
<div class="aa-ItemContent">
<div class="aa-ItemIcon aa-ItemIcon--noBorder">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"
/>
</svg>
</div>
<div class="aa-ItemContentBody">
<div class="aa-ItemContentTitle">
${components.Highlight({ hit: item, attribute: 'title' })}
</div>
</div>
</div>
</div>
</a>
`;
});
});
Example of beforeAutocompletePagesTemplate(_defaultTemplate, templateOptions, itemLink)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompletePagesTemplate', function(_defaultTemplate, templateOptions, itemLink) {
const { html, item, components } = templateOptions;
return html`
<a href="${itemLink}" class="aa-ItemLink aa-ProductItem">
<div class="aa-ItemWrapper">
<div class="aa-ItemContent">
<div class="aa-ItemIcon aa-ItemIcon--noBorder">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="aa-ItemContentBody">
<div class="aa-ItemContentTitle">
${components.Highlight({ hit: item, attribute: 'title' })}
</div>
</div>
</div>
</div>
</a>
`;
});
});
Example of beforeAutocompleteSuggestionsTemplate(defaultTemplate, templateOptions)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteSuggestionsTemplate', function(_defaultTemplate, templateOptions) {
const { html, state } = templateOptions;
return html`
<a
class="aa-ItemLink aa-ItemWrapper"
href="${window.Shopify.routes.root}search?q=${item.query}"
>
<div class="aa-ItemContent">
<div class="aa-ItemIcon aa-ItemIcon--noBorder">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z" />
</svg>
</div>
<div class="aa-ItemContentBody">
<div class="aa-ItemContentTitle">
${components.Highlight({ hit: item, attribute: 'query' })}
</div>
</div>
</div>
<div class="aa-ItemActions">
<button
class="aa-ItemActionButton"
title={"Fill query with ${item.query}"}
>
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M8 17v-7.586l8.293 8.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-8.293-8.293h7.586c0.552 0 1-0.448 1-1s-0.448-1-1-1h-10c-0.552 0-1 0.448-1 1v10c0 0.552 0.448 1 1 1s1-0.448 1-1z" />
</svg>
</button>
</div>
</a>
`;
});
});
Example of beforeAutocompleteHeaderTemplate(defaultTemplate, templateOptions)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAutocompleteHeaderTemplate', function(_defaultTemplate, templateOptions, resource) {
// Modify default options, then return them
const { html, state } = templateOptions;
const { query } = state;
return html`
<div class="aa-SourceHeader">
<span class="aa-SourceHeaderTitle">
${`Results for "${query}"`}
</span>
<div class="aa-SourceHeaderLine" />
</div>
`;
});
});
InstantSearch hooks
beforeInstantSearchConfigurationOptions(options)
- Used to modify default
instantsearch
options
- Used to modify default
beforeInstantSearchOptions(options)
- Contains
colors
,distinct
,facets
,hitsPerPage
,selector
, andsortOrders
- Contains
beforeInstantSearchAllowParamsArray(allowParamsArray)
- Preserves the URL parameters when navigating through the search results
beforeInstantSearchFiltersString(defaultFilter)
- Used to modify the filter parameter of the InstantSearch page
beforeInstantSearchMainTemplate(defaultTemplate, data, html)
- Renders the main template container
beforeInstantSearchProductTemplate(defaultTemplate, hit, html, components)
- Renders the product template
beforeInstantSearchNoResultTemplate(defaultTemplate, html)
- Renders the no results template
beforeInstantSearchFacetItemTemplate(defaultTemplate, item, html)
- Renders the facet items
beforeInstantSearchShowMoreTemplate(defaultTemplate, data, html)
- Renders the show more button
beforeInstantSearchStatsTemplate(defaultTemplate, data, html)
- Renders the stats
beforeISTransformItems(transformedItems, items)
- Used to modify items before they’re rendered
beforeISStartAddWidgetArray
- Used to add a widget to the InstantSearch page
- Please be aware not all widgets are available
- Return an array of widgets to add
afterISStartRemoveDefaultWidget(defaultWidgets)
- Default widget.widgetType:
ais.sortBy
,ais.searchBox
,ais.stats
,ais.hits
, andais.pagination
- Return an array of widgets to remove
- Default widget.widgetType:
afterInstantSearchHitClickAction(_, hit)
- Used to execute a function after a hit is clicked
beforeInstantSearchFacetLimitNumber(limit)
- Used to modify the default number of facets
- The default limit is 10
beforeISFacetSearchablePlaceholderString(placeHolder, facet)
- Used to modify the placeholder string for a searchable facet
beforeISFacetSearchableNoResultsString(noResults, facet)
- Used to modify the no results string for a searchable facet
- Return value can be a JavaScript template literal or a string
beforeInstantSearchFacetHeaderString(facetTitle, facet)
- Used to modify the facet header string
beforeInstantSearchFacetTransformItemsOptions(transformedItems, items)
- Used to modify facet items
beforeISearchInitSortOrdersArray(transformedSortOrders, sortOrder)
- Used to modify sort order
beforeISInitCollectionSortOrdersArray(transformedSortOrders, sortOrder)
- Used to modify the default sort orders.
Examples of InstantSearch hooks
Example of beforeInstantSearchConfigurationOptions(options)
hook:
1
2
3
4
5
6
7
8
9
// Modify default `options`
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchConfigurationOptions', function(options) {
// Modify default options, then return them
options.numberLocale: 'fr';
options.stalledSearchDelay: 500;
return options;
});
});
Example of beforeInstantSearchAllowParamsArray(allowParamsArray)
hook:
1
2
3
4
5
6
7
8
// Modify default `allowParamsArray`
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchAllowParamsArray', function(allowParamsArray) {
// Modify default array, then return an array
allowParamsArray.push('ref');
return allowParamsArray;
});
});
Example of beforeInstantSearchFiltersString(defaultFilter)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
// Modify default `defaultFilter` if it exists
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchFiltersString', function(defaultFilter) {
// Modify or replace the default string, then return a string
if(defaultFilter) {
return defaultFilter + ' AND price > 5'
}
else {
return 'price > 5'
}
});
});
Example of beforeInstantSearchMainTemplate(defaultTemplate, data, html)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchMainTemplate', function(_defaultTemplate, data, html) {
return html`
<div class="ais-page">
<h1 class="ais-h2">${algoliaShopify.translations.searchTitle}</h1>
<div class="ais-input">
<div class="ais-search-box-container"></div>
<div class="ais-input-button">
<div class="ais-clear-input-icon"></div>
</div>
</div>
<div class="ais-facets-button">
Show filters
</div>
<div class="ais-facets">
<div class="ais-clear-refinements-container"></div>
<div class="ais-current-refined-values-container"></div>
${data.facets.map(
facet =>
html`
<div
class="ais-facet-dropdown-wrapper ais-facet-${facet.type} ais-facet-${facet.escapedName}"
>
<label
for="${facet.escapedName}"
class="ais-range-slider--header ais-facet--header ais-header"
>${facet.title}</label
>
<input
class="ais-dropdown-checkbox"
type="checkbox"
id="${facet.escapedName}"
name="dropdown"
/>
<div
class="ais-facet-${facet.escapedName}-container ais-facet-dropdown-container"
></div>
</div>
`
)}
</div>
<div class="ais-block">
<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>
</div>
<div class="ais-sort">
${data.multipleSortOrders
? html`
${algoliaShopify.translations.sortBy}
<span class="ais-sort-orders-container"></span>
`
: html`
${algoliaShopify.translations.sortBy}
${algoliaShopify.translations.relevance}
`}
</div>
</div>
<div class="ais-hits-container ais-results-as-block"></div>
</div>
<div class="ais-pagination-container"></div>
</div>
`;
});
});
Example of beforeInstantSearchProductTemplate(defaultTemplate, hit, html, components)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchProductTemplate', function(_defaultTemplate, hit, html, components) {
return html`
<div
class="ais-hit ais-product"
data-algolia-index="${hit.index}"
data-algolia-position="${hit.productPosition}"
data-algolia-queryid="${hit.queryID}"
data-algolia-objectid="${hit.objectID}"
data-handle="${hit.handle}"
data-variant-id="${hit.objectID}"
data-distinct="${hit._distinct}"
data-product-id="${hit.id}"
>
<img
class="ais-hit--picture"
src="${algoliaShopify.helpers.mediumImage(hit)}"
alt="${hit.title} - ${hit.variant_title}"
/>
<div class="ais-hit--details">
<p class="ais-hit--title">
<a
data-algolia-index="${hit.index}"
data-algolia-position="${hit.productPosition}"
data-algolia-queryid="${hit.queryID}"
data-algolia-objectid="${hit.objectID}"
href="${algoliaShopify.helpers.instantsearchLink(hit)}"
onclick="void(0)"
title="${algoliaShopify.helpers.fullTitle(
hit.title,
hit._distinct,
hit.variant_title
)}"
>
${components.Highlight({ attribute: 'title', hit })}
${algoliaShopify.helpers.variantTitleAddition(hit, hit._distinct)}
</a>
</p>
<p
class="ais-hit--subtitle"
title="${hit.product_type}${algoliaShopify.translation_helpers.by(
hit.vendor
)}"
>
${components.Highlight({ attribute: 'product_type', hit })}
${hit.vendor &&
html`
<span> ${algoliaShopify.translations.by} </span>
`}
${hit.vendor && components.Highlight({ attribute: 'vendor', hit })}
</p>
<p class="ais-hit--price">
<b>${algoliaShopify.helpers.displayPrice(hit, hit._distinct)}</b>
${!hit._distinct &&
html`
<span class="ais-hit--price-striked"
><span
>${algoliaShopify.helpers.displayStrikedPrice(
hit.price,
hit.compare_at_price
)}</span
></span
>
`}
${!hit._distinct &&
html`
<span class="ais-hit--price-discount"
>${algoliaShopify.helpers.displayDiscount(
hit.price,
hit.compare_at_price,
hit.price_ratio
)}</span
>
`}
</p>
<!-- Extra info examples - Remove the display: none to show them -->
<p class="ais-hit--info" style="display: none">
${hit.sku &&
html`
<span class="algolia-sku"
>${components.Highlight({ attribute: 'sku', hit })}</span
>
`}
${hit.barcode &&
html`
<span class="algolia-barcode"
>${components.Highlight({ attribute: 'barcode', hit })}</span
>
`}
${hit.weight &&
html`
<span class="algolia-weight">${hit.weight}</span>
`}
${!hit.taxable &&
html`
<span class="algolia-taxable"
>${algoliaShopify.translations.taxFree}</span
>
`}
</p>
<!-- Tags example - Remove the display: none to show them -->
<p class="ais-hit--tags" style="display: none">
${hit?._highlightResult.tags?.map(
tag =>
html`
<span class="ais-hit--tag">${tag.value}</span>
`
)}
</p>
${!hit._distinct &&
html`
<form
id="algolia-add-to-cart-${hit.objectID}"
style="display: none;"
action="/cart/add"
method="post"
enctype="multipart/form-data"
>
<input type="hidden" name="id" value="${hit.objectID}" />
</form>
<p class="ais-hit--cart">
${hit.can_order
? html`
<button
class="ais-hit--cart-button"
data-form-id="algolia-add-to-cart-${hit.objectID}"
>
${algoliaShopify.translations.addToCart}
</button>
`
: html`
<button
class="ais-hit--cart-button ais-hit--cart-button__disabled"
>
${algoliaShopify.translations.outOfStock}
</button>
`}
</p>
`}
</div>
</div>
`;
});
});
Example of beforeInstantSearchNoResultTemplate(defaultTemplate, html)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchNoResultTemplate', function(_defaultTemplate, html) {
return html`
<div class="ais-hit-empty">
<div class="ais-hit-empty--title">
${algoliaShopify.translations.noResultFound}
</div>
<div class="ais-hit-empty--clears">
${algoliaShopify.translations.try} ${' '}
<a class="ais-hit-empty--clear-filters ais-link">
${algoliaShopify.translations.clearFilters} ${' '}
</a>
${algoliaShopify.translations.or} ${' '}
<a class="ais-hit-empty--clear-input ais-link">
${algoliaShopify.translations.changeInput}
</a>
</div>
</div>
`;
});
});
Example of beforeInstantSearchFacetItemTemplate(defaultTemplate, item, html)
hook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchFacetItemTemplate', function(_defaultTemplate, item, html) {
return html`
<label class="${item.cssClasses.label}">
${item.type === 'disjunctive' &&
(item.isRefined
? html`
<input
type="checkbox"
class="${item.cssClasses.checkbox}"
checked
/>
`
: html`
<input type="checkbox" class="${item.cssClasses.checkbox}" />
`)}
${item.label}
<span class="${item.cssClasses.count}">
${algoliaShopify.helpers.formatNumber(item.count)}
</span>
</label>
`;
});
});
Example of beforeInstantSearchShowMoreTemplate(defaultTemplate, data, html)
hook:
1
2
3
4
5
6
7
8
9
10
11
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchShowMoreTemplate', function(_defaultTemplate, data, html) {
return html`
<span
>${data.isShowingMore
? algoliaShopify.translations.showLess
: algoliaShopify.translations.showMore}</span
>
`;
});
});
Example of beforeInstantSearchFacetLimitNumber(limit)
hook:
1
2
3
4
5
6
7
// Modify default `limit`
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeInstantSearchFacetLimitNumber', function(limit) {
// Modify default limit, then return a number
return 12;
});
});
Example of afterISStartRemoveDefaultWidget(defaultWidgets)
hook:
1
2
3
4
5
6
7
8
9
10
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('afterISStartRemoveDefaultWidget', function(defaultWidgets) {
// Find and return the default pagination widget
const defaultPaginationWidget = defaultWidgets.find(
widget => widget.$$widgetType === 'ais.pagination'
);
return [defaultPaginationWidget];
});
});
Example of beforeISStartAddWidgetArray()
hook:
1
2
3
4
5
6
7
8
9
10
11
12
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeISStartAddWidgetArray', function() {
// Please be aware not all widgets are available
const { searchBox } = window.algoliaShopify.externals.widgets;
const searchBoxWidget = searchBox({
container: '#search-box'
});
return [searchBoxWidget];
});
});
Insights hook example
beforeAlgoliaAnalyticsOptions(options)
- Used to modify parameter options of the Insights library
beforeAddToCartSelectorString(selector)
- Used to modify the selector string for the add to cart button
Example of beforeAlgoliaAnalyticsOptions(options)
hook:
1
2
3
4
5
6
7
8
// Modify default `options`
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAlgoliaAnalyticsOptions', function(options) {
// Modify default options, then return them
options.userToken = 'd41951d5-4d0a-4907-8c1f-e98f6360e44d'; // random UUID;
return options;
});
});
Example of beforeAddToCartSelectorString(selector)
hook:
1
2
3
4
5
6
7
8
// Modify default `options`
document.addEventListener('algolia.hooks.initialize', function() {
algoliaShopify.hooks.registerHook('beforeAddToCartSelectorString', function(_selector) {
// The default selector is '[name="add"]'
// Return a CSS selector
return '#add-to-cart';
});
});