Integrations / Salesforce Commerce Cloud B2C

Integrate Algolia with a custom React frontend

This guide describes how to integrate Algolia into a headless Salesforce B2C Commerce storefront using a custom React frontend.

Unified InstantSearch for ecommerce for a Salesforce B2C Commerce headless storefront

To set up Algolia for your headless Salesforce B2C Commerce storefront, see Headless commerce.

Set up a React project

This guide uses Next.js but you can apply the instructions to any React project.

Create a new Next.js app with the create-next-app command-line tool.

1
2
3
npx create-next-app my-react-storefront
cd my-react-storefront
yarn dev

Running this command creates a new project in the directory my-react-storefront and starts a local development server on http://localhost:3000/.

Build your search experience

To create the search experience, you can either:

  1. Use the Unified InstantSearch package.
  2. Build a custom experience with React InstantSearch.

This guide uses the Unified InstantSearch package.

Download and run Unified InstantSearch

Clone the Unified InstantSearch 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 Unified InstantSearch for your data

Open the file unified-instantsearch-ecommerce/src/config/settings.js and make the following changes:

  1. Add your Algolia application ID, search API key, and index name:

    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: 'zzaa_001_sandbox_us01_dx__RefArch__products__en_US',
      //...
    }
    
  2. Configure your replica indices for sorting by “price” in ascending and descending order:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    export const sorts = [
      {
        label: 'Price ascending',
    -   value: 'instant_search_price_asc',
    +   value: `zzaa_001_sandbox_us01_dx__RefArch__products__en_US__price_USD_asc`,
      },
      {
        label: 'Price descending',
    -   value: `instant_search_price_desc`,
    +   value: `zzaa_001_sandbox_us01_dx__RefArch__products__en_US__price_USD_desc`,
      },
    ]
    
  3. Configure your category attributes.

    By default, the Algolia cartridge 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,
      },
    },
    
  4. Set your price attribute.

    By default, the Algolia cartridge indexes prices on the attributes price.${currency}:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    {
      type: 'slider',
      header: 'Price',
      label: 'Price',
      options: {
    -   attribute: `price`,
    +   attribute: `price.USD`,
        transformValue: (value) => (
          <>
            <span className="uni-Hit-currency">$</span>
            {value}
          </>
        ),
      },
    },
    
  5. Optional: remove query suggestions.

    If you don’t have Query Suggestions set up, remove the following code:

    1
    2
    3
    4
    5
    6
    
    - export const suggestionsIndex = {
    -   indexName: 'instant_search_demo_query_suggestions',
    -   searchParameters: {
    -     hitsPerPage: 6,
    -   },
    - };
    
  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
    
    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>
      );
    }
    

    The <Hit> component includes code for sending click events when users select a product in the search results.

Export the project

To make your frontend available in your storefront, you need to export it:

1
yarn export

Running this command creates a new directory unified-instantsearch-ecommerce/export with all assets.

Copy this directory to the public directory of your storefront project.

1
cp -r unified-instantsearch-ecommerce/export my-react-storefront/public/

Create a new <Search /> component

To use your React frontend in your storefront, create a new <Search /> component in the components directory.

1
2
mkdir -p my-react-storefront/components/Search
touch my-react-storefront/components/Search.js

Add the following code to the file: Search.js:

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
// 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 storefront

Open the file pages/index.js with your <Home /> component and add your <Search /> component to it.

Click and conversion events

To complete your setup, send click and conversion events.

Did you find this page helpful?