This guide describes how to integrate Findify with a single-page application (SPA) using the Merchant JS API .
This example uses React.js, but the main principle of shadow DOM should be working with Vue.js, Angular, Svelte and any other popular JavaScript framework.
You can have a look at the Findify Component example we've built on codesandbox
Import library
Add a script with store-specific code as mentioned in the instruction of our "Getting started guide" to the <span class="cm-s-neo" style="box-sizing: border-box;"><head></span>
section of your application.
HTML
</code></pre>
<div class="cm-s-neo" style="box-sizing: border-box;display: inherit;"><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: #9c3328;"><</span><span class="cm-tag" style="box-sizing: border-box;color: #9c3328;">script</span> <span class="cm-attribute" style="box-sizing: border-box;">src</span>=<span class="cm-string" style="box-sizing: border-box;color: #b35e14;">"//findify-assets-2bveeb6u8ag.netdna-ssl.com/search/prod/your-shop-domain.com.min.js"</span> <span class="cm-attribute" style="box-sizing: border-box;">async</span> <span class="cm-attribute" style="box-sizing: border-box;">defer</span><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: #9c3328;">></span><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: #9c3328;"></</span><span class="cm-tag" style="box-sizing: border-box;color: #9c3328;">script</span><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: #9c3328;">></span></div>
<pre style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: var(--font-size);margin-bottom: 15px;margin-top: 0px;overflow-wrap: normal;color: var(--md-code-text, inherit);line-height: 1.45;overflow: hidden;padding: 0px;display: block;word-break: normal;"><code class="rdmd-code lang-html theme-light" style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: 13.5px;background: inherit;border-radius: 3px;color: var(--md-code-text);margin: 0px;padding: 1em;border-width: 0px;white-space: pre;word-break: normal;line-height: inherit;overflow: auto;overflow-wrap: normal;max-height: 90vh;display: block;">
Wait for the library to be loaded
This function will return a promise which will be resolved right after Findify's JavaScript is completely loaded.
JavaScript
</code></pre>
<div class="cm-s-neo" style="box-sizing: border-box;display: inherit;"><span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">export</span> <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">const</span> <span class="cm-def" style="box-sizing: border-box;">waitForFindify</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> () <span class="cm-operator" style="box-sizing: border-box;">=></span> <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">new</span> <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">Promise</span>(<span class="cm-def" style="box-sizing: border-box;">resolve</span> <span class="cm-operator" style="box-sizing: border-box;">=></span> { (<span class="cm-variable" style="box-sizing: border-box;color: #047d65;">window</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">findifyCallbacks</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">window</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">findifyCallbacks</span> <span class="cm-operator" style="box-sizing: border-box;">||</span> []).<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">push</span>((<span class="cm-def" style="box-sizing: border-box;">findify</span>) <span class="cm-operator" style="box-sizing: border-box;">=></span> <span class="cm-variable-2" style="box-sizing: border-box;">resolve</span>(<span class="cm-variable-2" style="box-sizing: border-box;">findify</span>)); })</div>
<pre style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: var(--font-size);margin-bottom: 15px;margin-top: 0px;overflow-wrap: normal;color: var(--md-code-text, inherit);line-height: 1.45;overflow: hidden;padding: 0px;display: block;word-break: normal;"><code class="rdmd-code lang-javascript theme-light" style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: 13.5px;background: inherit;border-radius: 3px;color: var(--md-code-text);margin: 0px;padding: 1em;border-width: 0px;white-space: pre;word-break: normal;line-height: inherit;overflow: auto;overflow-wrap: normal;max-height: 90vh;display: block;">
Render
Once the node is ready you need to make sure Findify is ready and renders a widget into the node.
JavaScript
</code></pre>
<div class="cm-s-neo" style="box-sizing: border-box;display: inherit;"><span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">const</span> <span class="cm-def" style="box-sizing: border-box;">type</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> <span class="cm-string" style="box-sizing: border-box;color: #b35e14;">'search'</span>; <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// Type of widget</span> <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">const</span> <span class="cm-def" style="box-sizing: border-box;">widgetKey</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> <span class="cm-string" style="box-sizing: border-box;color: #b35e14;">'UNIQ_ID'</span>; <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">const</span> <span class="cm-def" style="box-sizing: border-box;">disableAutoRequest</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> <span class="cm-atom" style="box-sizing: border-box;color: #75438a;">true</span>; <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// Needs to be "true" to avoid an initial request</span> <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">const</span> <span class="cm-def" style="box-sizing: border-box;">findify</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">await</span> <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">waitForFindify</span>(); <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">findify</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">widgets</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">attach</span>(<span class="cm-variable" style="box-sizing: border-box;color: #047d65;">container</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">current</span>, <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">type</span>, { <span class="cm-meta" style="box-sizing: border-box;">...</span><span class="cm-variable" style="box-sizing: border-box;color: #047d65;">options</span>, <span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">widgetKey</span>, <span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">disableAutoRequest</span> }); <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">const</span> <span class="cm-def" style="box-sizing: border-box;">widget</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">findify</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">widgets</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">get</span>(<span class="cm-variable" style="box-sizing: border-box;color: #047d65;">widgetKey</span>); <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// Widget instance</span> <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">widget</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">agent</span> .<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">defaults</span>({ <span class="cm-meta" style="box-sizing: border-box;">...</span><span class="cm-variable" style="box-sizing: border-box;color: #047d65;">request</span> }) <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// Default request values</span> .<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">once</span>(<span class="cm-string" style="box-sizing: border-box;color: #b35e14;">'change:items'</span>, () <span class="cm-operator" style="box-sizing: border-box;">=></span> { <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// or 'change:suggestions' if it's for the autocomplete</span> <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// callback when items have been received</span> }) <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// For the autocomplete data will be fetched automatically, but for Search Widget you need to make an initial request manually. </span> <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">if</span> ([<span class="cm-string" style="box-sizing: border-box;color: #b35e14;">'search'</span>, <span class="cm-string" style="box-sizing: border-box;color: #b35e14;">'smart-collection'</span>].<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">includes</span>(<span class="cm-variable" style="box-sizing: border-box;color: #047d65;">type</span>)) { <span class="cm-keyword" style="box-sizing: border-box;color: #1d75b3;">const</span> <span class="cm-def" style="box-sizing: border-box;">query</span> <span class="cm-operator" style="box-sizing: border-box;">=</span> <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">findify</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">utils</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">getQuery</span>(); <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// Parse URL query</span> <span class="cm-variable" style="box-sizing: border-box;color: #047d65;">widget</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">agent</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">applyState</span>(<span class="cm-variable-2" style="box-sizing: border-box;">query</span>) <span class="cm-comment" style="box-sizing: border-box;color: #75787b;">// Request data</span> }</div>
<pre style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: var(--font-size);margin-bottom: 15px;margin-top: 0px;overflow-wrap: normal;color: var(--md-code-text, inherit);line-height: 1.45;overflow: hidden;padding: 0px;display: block;word-break: normal;"><code class="rdmd-code lang-javascript theme-light" style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: 13.5px;background: inherit;border-radius: 3px;color: var(--md-code-text);margin: 0px;padding: 1em;border-width: 0px;white-space: pre;word-break: normal;line-height: inherit;overflow: auto;overflow-wrap: normal;max-height: 90vh;display: block;">
Check out our Merchant JS API for further information on how to use Findify!
Unmount
To void memory leaks detach the Findify instance after the node has unmounted.
JavaScript
</code></pre>
<div class="cm-s-neo" style="box-sizing: border-box;display: inherit;"><span class="cm-variable" style="box-sizing: border-box;color: #047d65;">findify</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">widgets</span>.<span class="cm-property" style="box-sizing: border-box;color: #1d75b3;">detach</span>(<span class="cm-variable" style="box-sizing: border-box;color: #047d65;">widgetKey</span>)</div>
<pre style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: var(--font-size);margin-bottom: 15px;margin-top: 0px;overflow-wrap: normal;color: var(--md-code-text, inherit);line-height: 1.45;overflow: hidden;padding: 0px;display: block;word-break: normal;"><code class="rdmd-code lang-javascript theme-light" style="box-sizing: border-box;font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);font-size: 13.5px;background: inherit;border-radius: 3px;color: var(--md-code-text);margin: 0px;padding: 1em;border-width: 0px;white-space: pre;word-break: normal;line-height: inherit;overflow: auto;overflow-wrap: normal;max-height: 90vh;display: block;">
History Navigation
There is no generic solution to use custom History instances in Findify Widgets, so you need to rise your one in the global scope and make changes to Findify components via Chrome using our DevTools.