Build Atomic commerce interfaces without using the Coveo app for Shopify
Build Atomic commerce interfaces without using the Coveo app for Shopify
This page explains how to integrate Atomic search box, search page, product listing page, and recommendation components in a Shopify store. The details will vary depending on the theme you’re using, but the core logic remains the same.
This article uses the default Dawn theme as an example starting point.
|
This article assumes that you’re not using the Coveo AI Search & Discovery app, which allows for certain simplifications. If you’re using the app, see Build Atomic commerce interfaces in a Shopify store with the Coveo AI Search & Discovery app. |
Load Atomic and build the Commerce engine
-
In your Shopify theme editor
, create a snippet titled
atomic.liquid
and paste the following code. For optimization purposes, it relies on promises.
<!-- snippets/atomic.liquid --> <script type="module"> window.loadAtomic = function () { if (document.getElementById('atomic-script')) {
return customElements.whenDefined('atomic-commerce-interface');
} var script = document.createElement('script'); script.src = 'https://static.cloud.coveo.com/atomic/v3/atomic.esm.js';
script.type = 'module'; script.setAttribute('id', 'atomic-script'); document.head.appendChild(script); var css = document.createElement('link'); css.rel = 'stylesheet'; css.href = 'https://static.cloud.coveo.com/atomic/v3/themes/coveo.css';
document.head.appendChild(css); return customElements.whenDefined('atomic-commerce-interface'); }; </script>
Checks whether the Atomic scripts have already been loaded. Return a promise that resolves when the atomic-commerce-interface
custom element is defined.The Atomic Commerce JavaScript module. The Atomic Commerce CSS file. -
Create a snippet titled
engine.liquid
in which you paste the following code, replacing the placeholders with your own values.<!-- snippets/engine.liquid --> <script type="module"> window.configureHeadless = function() { return new Promise((resolve)=> { if(window.CoveoEngine) { resolve(window.CoveoEngine); } else { import('https://static.cloud.coveo.com/headless/v3/commerce/headless.esm.js').then(({ buildCommerceEngine
}) => { const engine = buildCommerceEngine({ configuration : { accessToken: '<ACCESS_TOKEN>',
organizationId: '<ORGANIZATION_ID>',
analytics: { enabled: true, trackingId: '<TRACKING_ID>',
}, context: {
country: {{ localization.country.iso_code | json }}, currency: {{ localization.country.currency.iso_code | json }}, view: { url: {{ canonical_url | json }}, }, language: {{ request.locale.iso_code | json }}, cart: {{ cart.items | json }}.map(function (item) { return { productId: item.product_id, name: item.title, price: item.final_price, quantity: item.quantity, }; }), } }}) window.CoveoEngine = engine; resolve(engine); }); } }) } </script>
You’ll need the buildCommerceEngine
function from theheadless
module to build your Commerce engine just below.An access token with the Search - Execute queries - Allowed and Analytics - Analytics data - Push privileges. Your organization ID. The target tracking ID. The context
object containing the country, currency, view, language, and cart information, extracted from the Shopify store.
You’ll need to include this snippet in every page of your Shopify store in which you want to use Coveo Atomic Commerce components.
Search page
To implement a Coveo Atomic search page or replace an existing search page with a Coveo Atomic search page, you need to:
-
Create a snippet named
initialize-search-page.liquid
to initialize the Atomic interface.<!-- snippets/initialize-search-page.liquid --> <script type="module"> Promise.all([ window.loadAtomic(), window.configureHeadless(), ]).then(() => {
const searchPage = document.querySelector('#search-page'); searchPage.initializeWithEngine(window.CoveoEngine).then(function () { searchPage.executeFirstRequest();
}); }); </script>
When promises are resolved, initialize the search page with the Coveo engine. The executeFirstRequest
method sends the first query to the Coveo engine, ensuring the search page is populated with results when it loads. -
Remove the existing search page mechanism, if any. In the Dawn theme, this code is located in
sections/main-search.liquid
.Replace it with with the target initialization snippets and an
atomic-commerce-interface
element of typesearch
that includes the target Atomic search page components, as follows:<!--- sections/main-search.liquid ---> {% render 'engine' %} {% render 'atomic' %} {% render 'initialize-search-page' %} <atomic-commerce-interface id="search-page" type="search"> <atomic-commerce-layout> <atomic-layout-section section="search"> <atomic-commerce-search-box> <atomic-commerce-search-box-recent-queries></atomic-commerce-search-box-recent-queries> <atomic-commerce-search-box-query-suggestions></atomic-commerce-search-box-query-suggestions> <atomic-commerce-search-box-instant-products image-size="small"> <atomic-product-template> <template> <atomic-product-section-name> <atomic-product-link></atomic-product-link> </atomic-product-section-name> <atomic-product-section-visual> <atomic-product-field-condition if-defined="ec_thumbnails">
<atomic-product-image field="ec_thumbnails"></atomic-product-image> </atomic-product-field-condition> </atomic-product-section-visual> <atomic-product-section-metadata> <atomic-product-field-condition if-defined="ec_brand"> <atomic-product-text field="ec_brand"></atomic-product-text> </atomic-product-field-condition> <atomic-product-field-condition if-defined="ec_rating"> <atomic-product-rating field="ec_rating"></atomic-product-rating> </atomic-product-field-condition> </atomic-product-section-metadata> <atomic-product-section-emphasized> <atomic-product-price></atomic-product-price> </atomic-product-section-emphasized> <atomic-product-section-children> <atomic-product-children></atomic-product-children> </atomic-product-section-children> </template> </atomic-product-template> </atomic-commerce-search-box-instant-products> </atomic-commerce-search-box> </atomic-layout-section> <atomic-layout-section section="facets"><atomic-commerce-facets></atomic-commerce-facets></atomic-layout-section> <atomic-layout-section section="main"> <atomic-layout-section section="status"> <atomic-commerce-breadbox></atomic-commerce-breadbox> <atomic-commerce-query-summary></atomic-commerce-query-summary> <atomic-commerce-sort-dropdown></atomic-commerce-sort-dropdown> <atomic-commerce-did-you-mean></atomic-commerce-did-you-mean> <atomic-commerce-refine-toggle></atomic-commerce-refine-toggle> </atomic-layout-section> <atomic-layout-section section="products"> <atomic-commerce-product-list display="grid" density="compact" image-size="small"> <atomic-product-template> <template> <atomic-product-section-name id="product-name-section"> <atomic-product-link></atomic-product-link> </atomic-product-section-name> <atomic-product-section-visual> <atomic-product-field-condition if-defined="ec_thumbnails"> <atomic-product-image field="ec_thumbnails"></atomic-product-image> </atomic-product-field-condition> </atomic-product-section-visual> <atomic-product-section-metadata> <atomic-product-field-condition if-defined="ec_brand"> <atomic-product-text field="ec_brand"></atomic-product-text> </atomic-product-field-condition> <atomic-product-field-condition if-defined="ec_rating"> <atomic-product-rating field="ec_rating"></atomic-product-rating> </atomic-product-field-condition> </atomic-product-section-metadata> <atomic-product-section-emphasized> <atomic-product-price></atomic-product-price> </atomic-product-section-emphasized> <atomic-product-section-description> <atomic-product-excerpt></atomic-product-excerpt> </atomic-product-section-description> <atomic-product-section-children> <atomic-product-children></atomic-product-children> </atomic-product-section-children> </template> </atomic-product-template> </atomic-commerce-product-list> <atomic-commerce-query-error></atomic-commerce-query-error> <atomic-commerce-no-products></atomic-commerce-no-products> </atomic-layout-section> <atomic-layout-section section="pagination"> <atomic-commerce-load-more-products></atomic-commerce-load-more-products> </atomic-layout-section> </atomic-layout-section> </atomic-commerce-layout> </atomic-commerce-interface>
The ec_thumbnails
is a standard commerce field that contains the product images. Adjust this property if you use another field to store the product thumbnails.
Standalone search box
Most likely, you’ll want to add a standalone search box on every page of your website. Also, you’ll want to disable it on the search page, which already includes a search box.
-
Create a snippet named
initialize-ssb.liquid
to initialize the standalone search box, as follows:<!-- snippets/initialize-ssb.liquid --> <script type="module"> window.handleCoveoSearchboxClick = function () { Promise.all([ window.loadAtomic(), window.configureHeadless() ]).then(() => { const standaloneSearchBox = document.querySelector('#standalone-search-box'); if (!standaloneSearchBox.hasAttribute('atomic-initialized')) { standaloneSearchBox.initializeWithEngine(window.CoveoEngine); standaloneSearchBox.setAttribute('atomic-initialized', 'true');
} }); }; </script>
Ensures that the standalone search box is only initialized once. -
Remove the existing search box markup. In the Dawn theme, this markup is located in
snippets/header-search.liquid
. Replace it with the following:<!--- snippets/header-search.liquid ---> {% if request.path != '/search' %}
{% render 'atomic' %} {% render 'engine' %} {% render 'initialize-ssb' %} <details-modal> <details> <summary class="header__icon header__icon--search header__icon--summary link focus-inset modal__toggle" aria-haspopup="dialog" > <button id="search-button" aria-label="Search" class="svg-wrapper" onclick="handleCoveoSearchboxClick()"> <span class="svg-wrapper"> {{- 'icon-search.svg' | inline_asset_content -}}
</span> </button> </summary> <div class="search-modal modal__content gradient" role="dialog" aria-modal="true" > <div class="modal-overlay"></div> <div tabindex="-1" class="standalone-search-box-container" > <atomic-commerce-interface type="search" id="standalone-search-box"> <atomic-layout-section section="search"> <atomic-commerce-search-box redirection-url="/search"> <atomic-commerce-search-box-recent-queries></atomic-commerce-search-box-recent-queries> <atomic-commerce-search-box-query-suggestions></atomic-commerce-search-box-query-suggestions> <atomic-commerce-search-box-instant-products image-size="small"> <atomic-product-template> <template> <atomic-product-section-name> <atomic-product-link></atomic-product-link> </atomic-product-section-name> <atomic-product-section-visual> <atomic-product-image field="ec_thumbnails"></atomic-product-image> </atomic-product-section-visual> <atomic-product-section-metadata> <atomic-product-text field="ec_brand"></atomic-product-text> <atomic-product-rating field="ec_rating"></atomic-product-rating> </atomic-product-section-metadata> <atomic-product-section-emphasized> <atomic-product-price></atomic-product-price> </atomic-product-section-emphasized> <atomic-product-section-children> <atomic-product-children></atomic-product-children> </atomic-product-section-children> </template> </atomic-product-template> </atomic-commerce-search-box-instant-products> </atomic-commerce-search-box> </atomic-layout-section> </atomic-commerce-interface> <div class="hidden"><input></div>
<button type="button" class="search-modal__close-button modal__close-button link link--text focus-inset" aria-label="{{ 'accessibility.close' | t }}" > <span class="svg-wrapper"> {{- 'icon-close.svg' | inline_asset_content -}} </span> </button> </div> </div> </details> </details-modal> {% endif %}
Don’t display the standalone search box on the search page, since it already includes a search box. This image is from the Dawn theme. Replace it with the appropriate SVG icon for your theme, as needed. This div
and the followingbutton
are carried over from the Dawn theme for modal handling. Customize this markup to fit your theme, as needed. -
Style your standalone search box. The CSS classes and styles you need to apply to your standalone search box depend on your theme. In the Dawn theme, create a
ssb.css
file in theassets
folder:/* assets/ssb.css */ .standalone-search-box-container { width: 80%; display: flex; justify-content: center; } #search-button { background: white; border: white; cursor: pointer; } #search-button:hover { transform: scale(1.07); }
Then, add the following to render this CSS file in your
header-search.liquid
file:{{ 'ssb.css' | asset_url | stylesheet_tag }}
Product listing page
To implement a Coveo Atomic product listing page or replace an existing product listing page with a Coveo Atomic product listing page, you need to:
-
Create the target listing configurations. The Coveo AI Search & Discovery app doesn’t currently create listing configurations automatically, so you need to create them yourself whether you’re using the app or not.
-
Create a snippet named
initialize-plp.liquid
to initialize the Atomic interface.<!-- snippets/initialize-plp.liquid --> <script type="module"> Promise.all([ window.loadAtomic(), window.configureHeadless(), ]).then(() => { const productList = document.querySelector('#product-listing'); productList.initializeWithEngine(window.CoveoEngine).then(() => { productList.executeFirstRequest(); }); }); </script>
-
Remove the existing product listing page mechanism. In the Dawn theme, an example file is
sections/collection-template.liquid
. Replace it with the target initialization snippets and anatomic-commerce-interface
element of typeproduct-listing
that includes the target Atomic product listing page components, as follows:{% render 'engine' %} {% render 'atomic' %} {% render 'initialize-plp' %} <atomic-commerce-interface id="product-listing" type="product-listing"> <atomic-commerce-layout> <atomic-layout-section section="facets"><atomic-commerce-facets></atomic-commerce-facets></atomic-layout-section> <atomic-layout-section section="main"> <atomic-layout-section section="status"> <atomic-commerce-breadbox></atomic-commerce-breadbox> <atomic-commerce-query-summary></atomic-commerce-query-summary> <atomic-commerce-sort-dropdown></atomic-commerce-sort-dropdown> <atomic-commerce-refine-toggle></atomic-commerce-refine-toggle> </atomic-layout-section> <atomic-layout-section section="products"> <atomic-commerce-product-list display="grid" density="compact" image-size="small"> <atomic-product-template> <template> <atomic-product-section-name> <atomic-product-link></atomic-product-link> </atomic-product-section-name> <atomic-product-section-visual> <atomic-product-image field="ec_thumbnails"></atomic-product-image> </atomic-product-section-visual> <atomic-product-section-children> <atomic-product-children></atomic-product-children> </atomic-product-section-children> <atomic-product-section-metadata> <atomic-product-text field="ec_brand"></atomic-product-text> <atomic-product-rating field="ec_rating"></atomic-product-rating> </atomic-product-section-metadata> <atomic-product-section-emphasized> <atomic-product-price></atomic-product-price> </atomic-product-section-emphasized> <atomic-product-section-description> <atomic-product-description></atomic-product-description> </atomic-product-section-description> </template> </atomic-product-template> </atomic-commerce-product-list> <atomic-commerce-query-error></atomic-commerce-query-error> <atomic-commerce-no-products></atomic-commerce-no-products> </atomic-layout-section> <atomic-layout-section section="pagination"> <atomic-commerce-load-more-products></atomic-commerce-load-more-products> </atomic-layout-section> </atomic-layout-section> </atomic-commerce-layout> </atomic-commerce-interface>
Recommendations
To implement Coveo Atomic recommendations or replace existing recommendations with Coveo Atomic recommendations, you need to:
-
Create the target recommendation configurations. The Coveo AI Search & Discovery app doesn’t currently create recommendation configurations automatically, so you need to create them yourself whether you’re using the app or not.
-
Create a snippet named
initialize-recs.liquid
to initialize the Atomic interface.<!-- snippets/initialize-recs.liquid --> <script type="module"> Promise.all([ window.loadAtomic(), window.configureHeadless(), ]).then(() => { const recs = document.querySelector('#recs-component'); recs.initializeWithEngine(window.CoveoEngine); }); </script>
-
Remove the existing recommendations mechanism. In the Dawn theme, an example file is
featured-collection.liquid
. Replace it with the target initialization snippets and anatomic-commerce-recommendation-interface
element that includes the target Atomic recommendations components, as follows:{% render 'engine' %} {% render 'atomic' %} {% render 'initialize-recs' %} <atomic-commerce-recommendation-interface class="page-width" id="recs-component"> <atomic-commerce-layout> <atomic-layout-section section="main"> <atomic-commerce-recommendation-list slot-id=<SLOT_ID>
> <atomic-product-template> <template> <atomic-product-section-name> <atomic-product-link></atomic-product-link> </atomic-product-section-name> <atomic-product-section-visual> <atomic-product-image field="ec_thumbnails"></atomic-product-image> </atomic-product-section-visual> <atomic-product-section-metadata> <atomic-product-field-condition if-defined="ec_brand"> <atomic-product-text field="ec_brand"></atomic-product-text> </atomic-product-field-condition> <atomic-product-field-condition if-defined="ec_brand"> <atomic-product-rating field="ec_rating"></atomic-product-rating> </atomic-product-field-condition> </atomic-product-section-metadata> <atomic-product-section-description> <atomic-product-text field="ec_shortdesc"></atomic-product-text> </atomic-product-section-description> <atomic-product-section-emphasized> <atomic-product-price></atomic-product-price> </atomic-product-section-emphasized> <atomic-product-section-children> <atomic-product-children></atomic-product-children> </atomic-product-section-children> </template> </atomic-product-template> </atomic-commerce-recommendation-list> </atomic-layout-section> </atomic-commerce-layout> </atomic-commerce-recommendation-interface>
Replace <SLOT_ID>
with the target slot ID for your recommendations. The slot ID is returned when you create recommendation configurations.
What’s next?
To see what Atomic Commerce components exist and the available options, see the reference documentation.
To learn more on the Coveo Atomic library, see the Atomic documentation.