Use Coveo Search in SAP Commerce Cloud Composable Storefront

This is for:

Developer

SAP Commerce Cloud composable storefront (previously SAP Spartacus) is built upon Angular, which Coveo Atomic supports natively.

This article explains the steps required to build a basic search UI in SAP Commerce Cloud composable storefront using the Atomic framework.

Create an app

  1. Create a new Angular app

    ng new mystore --style=scss

    When prompted for Angular routing, enter n for no.

  2. Go to the newly created directory

    cd mystore
  3. To install SAP Commerce Cloud composable storefront, you have to use the Spartacus schematics to quickly set up your application.

    For the base-url and base-site parameters, use values from your SAP Commerce instance.

    ng add @spartacus/schematics@latest --base-url https://api.your-instance.commerce.ondemand.com/ --base-site=your-site --language=en --ssr
    Note

    During the installation, you’ll be prompted to choose which features you want to set up. If you want to build a B2B storefront, select the relevant B2B feature(s).

    For more details on available features, see the SAP documentation.

  4. Install the dependencies.

    yarn install
  5. To specify the path to your OCC, go to the the src/environments directory.

    In the environments and environments.prod.ts files, update the environment object with the following parameter:

    occBaseUrl: 'https://api.your.instance.commerce.ondemand.com/'
  6. Open the tsconfig.json file and update the compilerOptions object with the following:

    "compilerOptions": {
      // ...
      "allowSyntheticDefaultImports": true
    },

Adjust the app to use Coveo

To use Coveo-based search in your project, perform the following steps.

  1. Install the Atomic Angular package

    npm i @coveo/atomic-angular
  2. Move the Atomic static assets to the src directory of your app and update the angular.json file accordingly.

  3. To add basic styling, include the Default Coveo Theme.

  4. To be able to use the Atomic Angular components, open the src/app/app.module.ts file and import the AtomicAngular module.

  5. To initialize the search interface, update the src/app/app.component.ts file:

    import { AfterViewInit, Component } from '@angular/core';
    import { loadFieldActions } from '@coveo/atomic-angular'
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    
    export class AppComponent implements AfterViewInit {
      ngAfterViewInit(): void {
        const searchInterface = document.querySelector('atomic-search-interface');
        searchInterface
          ?.initialize({
            accessToken: 'xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 1
            organizationId: 'orgnameplaceholder',
          })
          .then(() => {
            const engine = searchInterface.engine;
    
            if (engine) {
              const fieldActions = loadFieldActions(engine);
              engine.dispatch(fieldActions.registerFieldsToInclude([ 2
                'ec_brand',
                'ec_category',
                'ec_image',
                'ec_price'
              ]));
              searchInterface.executeFirstSearch();
            }
          });
      }
    }
    1 Specifies credentials for the target Coveo organization. See Authenticate via search token and Use API key authentication with the Search API.
    2 Specifies what custom fields to use in the UI.

Build a search UI

Now that you imported and initialized Coveo Atomic, you can use Atomic components to build a UI.

  1. As a starting point, paste the following sample into the src/app/app.component.html file:

    <atomic-search-interface>
      <atomic-search-layout>
        <atomic-layout-section section="search">
          <atomic-search-box></atomic-search-box>
        </atomic-layout-section>
        <atomic-layout-section section="facets">
          <atomic-facet-manager>
            <!-- The custom field dispatched in app.component.ts -->
            <atomic-category-facet
              field="ec_category"
              label="Category"
            ></atomic-category-facet>
            <!-- The custom field dispatched in app.component.ts -->
            <atomic-facet
              field="ec_brand"
              label="Brand"
            ></atomic-facet>
            <!-- The custom field dispatched in app.component.ts -->
            <atomic-numeric-facet
              field="ec_price"
              label="Price"
            ></atomic-numeric-facet>
          </atomic-facet-manager>
        </atomic-layout-section>
        <atomic-layout-section section="main">
          <atomic-layout-section section="status">
            <atomic-refine-toggle></atomic-refine-toggle>
            <atomic-query-summary></atomic-query-summary>
            <atomic-sort-dropdown>
              <atomic-sort-expression label="relevance" expression="relevancy"></atomic-sort-expression>
              <!-- The custom field dispatched in app.component.ts -->
              <atomic-sort-expression label="Price (high to low)" expression="ec_price descending"></atomic-sort-expression>
              <!-- The custom field dispatched in app.component.ts -->
              <atomic-sort-expression label="Price (low to high)" expression="ec_price ascending"></atomic-sort-expression>
            </atomic-sort-dropdown>
          </atomic-layout-section>
          <atomic-layout-section section="results">
            <atomic-result-list
              display="grid"
              image-size="large"
            >
              <atomic-result-template>
                <template>
                  <atomic-result-text field="title"></atomic-result-text>
                  <atomic-result-section-visual>
                    <!-- The custom field dispatched in app.component.ts -->
                    <atomic-result-image field="ec_image"></atomic-result-image>
                  </atomic-result-section-visual>
                  <atomic-result-section-excerpt>
                    <atomic-result-text field="excerpt"></atomic-result-text>
                  </atomic-result-section-excerpt>
                </template>
              </atomic-result-template>
            </atomic-result-list>
          </atomic-layout-section>
          <atomic-layout-section section="pagination">
            <atomic-load-more-results></atomic-load-more-results>
          </atomic-layout-section>
        </atomic-layout-section>
      </atomic-search-layout>
    </atomic-search-interface>
    Important

    To see search results, make sure that your Coveo organization already has data indexed from an SAP Commerce Cloud instance.

  2. To launch the application locally, run the yarn start command. The application will open in the browser, at the http://localhost:4200 address by default.

  3. You now have a basic search interface powered by Coveo! Feel free to modify and experiment with it. You can add or remove components in the markup, type in requests in the search bar, use facets on the left side, click the results, etc.

Sample implementation

To see a more advanced implementation, examine the Coveo Barca demo.