Connecting to Headless Salesforce Commerce Cloud Using a React Front End
By nature, headless architectures allow for more agility and flexibility. Therefore, various, very different approaches are labeled “headless.” This guide describes how the Algolia Salesforce Commerce Cloud integration can fit in headless architecture and support its intended flexibility.
There are multiples ways to spin up a headless architecture with Salesforce Commerce Cloud (SFCC) B2C. There are three main steps to integrating Algolia with SFCC Headless:
- Install the Algolia Link integration.
- Index your catalogs to Algolia.
- Connect to a headless storefront.
This guide describes, how to connect Algolia to a headless SFCC storefront using React. If you prefer to use the official boilerplate published by Salesforce, please refer to the guide on connecting a headless Salesforce Commerce Cloud using official boilerplate. Regardless of which method you use, the first two steps (installing the Algolia link Integration and indexing your catalogs to Algolia) are the same.
Install the Algolia Link integration
The Algolia Link is composed of four cartridges that work together to fit in various uses cases.
Unlike SiteGenesis or Storefront reference architectures (SFRA), headless architectures only use the “server-side” cartridges, namely: int_algolia
and bm_algolia
.
| int_algolia | Handles the import of your product information from Salesforce Commerce Cloud to Algolia | | bm_algolia | Allows you to monitor and configure Algolia indexing from your Business Manager |
To complete the installation, please follow the instructions in Set Up the Algolia Cartridge.
Index your catalogs
To index your catalogs, please follow the instructions in Index Your Catalogs to Algolia .
After successfully running the indexing jobs, navigate to the Indices section of the Algolia dashboard to ensure your catalogs are properly indexed.
Connect to a headless storefront
You can connect Algolia to a headless SFCC storefront using React in few steps:
- Set up a React based project.
- Use Algolia’s Unified UI package or React InstantSearch library to build out your search experience.
Set up a React based project
This guide uses Next.js but you can transpose the instructions to any React-based project.
Create a React/Next.js project using create-next-app.
1
2
3
npx create-next-app my-react-storefront
cd my-react-storefront
yarn dev
This create the project in the directory my-react-storefront
and starts a server on http://localhost:3000/.
Build your search experience
To create the search experience, you can either:
- Use the out-the-box Unified InstantSearch Ecommerce package.
- Build a tailor-made experience with React InstantSearch.
This guide uses the Unified InstantSearch Ecommerce package.
Download and run the project
Clone the project’s GitHub repository.
1
2
3
4
git clone --depth=1 --branch=master https://github.com/algolia/unified-instantsearch-ecommerce
rm -rf unified-instantsearch-ecommerce/.git
cd unified-instantsearch-ecommerce
yarn && yarn start
Configure the package to work with your data
Open unified-instantsearch-ecommerce/src/config/settings.js
and make the following changes:
Set you Application ID, search API key and index
1
2
3
4
5
6
7
8
9
10
- export const appId = 'latency';
- export const searchApiKey = '6be0576ff61c053d5f9a3225e2a90f76';
+ export const appId = '<Your Algolia Application ID>';
+ export const searchApiKey = '<Your Algolia Search-only API Key>';
export const index = {
- indexName: 'instant_search',
+ indexName: 'zzgk_001_sandbox_us01_dx__RefArch__products__en_US',
...
}
Set your “Price ascending” and “Price descending” index replicas
1
2
3
4
5
6
7
8
9
10
11
12
export const sorts = [
{
label: 'Price ascending',
- value: 'instant_search_price_asc',
+ value: `zzgk_001_sandbox_us01_dx__RefArch__products__en_US__price_USD_asc`,
},
{
label: 'Price descending',
- value: `instant_search_price_desc`,
+ value: `zzgk_001_sandbox_us01_dx__RefArch__products__en_US__price_USD_desc`,
},
]
Set your category attributes
The Algolia Integration by default indexes the primary category on the attributes __primary_category.*
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
type: 'hierarchical',
header: 'Categories',
label: 'Category',
options: {
attributes: [
- 'hierarchicalCategories.lvl0',
- 'hierarchicalCategories.lvl1',
+ '__primary_category.0',
+ '__primary_category.1',
+ '__primary_category.2',
],
limit: 6,
showMore: true,
},
},
Set your price attribute
The Algolia integration, by default, indexes prices on the attributes price.${currency}
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
type: 'slider',
header: 'Price',
label: 'Price',
options: {
- attribute: `price`,
+ attribute: `price.USD`,
transformValue: (value) => (
<>
<span className="uni-Hit-currency">$</span>
{value}
</>
),
},
},
Remove suggestions configuration
This part of the configuration creates a Query Suggestions UI. Unless you have set this feature up, you shouldn’t include it.
1
2
3
4
5
6
- export const suggestionsIndex = {
- indexName: 'instant_search_demo_query_suggestions',
- searchParameters: {
- hitsPerPage: 6,
- },
- };
Customize the Hit
component
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
export function Hit({ hit, insights, view }) {
+ const image = hit.image_groups[1].images[0];
return (
<article
className="uni-Hit"
onClick={() =>
insights('clickedObjectIDsAfterSearch', {
eventName: 'Product Clicked',
})
}
>
<a href={hit.url} className="uni-Hit-inner">
<div className="uni-Hit-image">
- <img src={hit.image} alt={hit.name} loading="lazy" />
+ <img src={image.dis_base_link} alt={image.alt} loading="lazy" />
</div>
<div className="uni-Hit-Body">
<header className="uni-Hit-header">
<h2 className="uni-Hit-category">{hit.categories[0]}</h2>
<h1 className="uni-Hit-title">
<Highlight attribute="name" tagName="mark" hit={hit} />
</h1>
</header>
{view === 'list' && (
<p className="uni-Hit-description">
- <Snippet attribute="description" tagName="mark" hit={hit} />
+ <Snippet attribute="short_description" tagName="mark" hit={hit} />
</p>
)}
<footer>
<span className="uni-Hit-currency">$</span>
- <span className="uni-Hit-price">{hit.price.toLocaleString()}</span>
+ <span className="uni-Hit-price">{hit.price.USD.toLocaleString()}</span>
</footer>
</div>
...
</a>
</article>
);
}
Compile and export the project
Once you’ve finished customizing your front end, you need to export it so it can be used in your storefront.
1
yarn export
This produces a directory unified-instantsearch-ecommerce/export
containing all the assets needed to power a complete ecommerce search experience.
Copy this directory to the public
directory of your storefront project.
1
cp -r unified-instantsearch-ecommerce/export my-react-storefront/public/
Use the exported assets
Create a new Search component
1
2
mkdir -p my-react-storefront/components/Search
touch my-react-storefront/components/Search.js
Fill your newly created Search.js
file with the following contents:
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
// in my-react-storefront/components/Search.js
import React from 'react';
import Head from "next/head";
export default function Search() {
React.useEffect(() => {
// remove the script if already exists
let script = document.querySelector(`script[src="${src}"]`);
if (script) {
script.remove();
}
// add script to DOM
script = document.createElement("script");
script.src = src;
document.body.appendChild(script);
return () => {
// remove the script on unmount
document.querySelector(`script[src="${src}"]`).remove();
};
});
return (
<>
<Head>
<link rel="stylesheet" async href="/export/search.css" />
</Head>
<div id="search-button" />
</>
);
}
Use your Search component in your UI
Finally, open your Home
component, located in the file: pages/index.js
, and mount the newly created <Search />
component in it.