Use Coveo Search in SAP Commerce Cloud Composable Storefront
Use Coveo Search in SAP Commerce Cloud Composable Storefront
SAP Commerce Cloud composable storefront (previously SAP Spartacus) is built upon Angular, which Coveo Atomic supports natively.
This article explains how to include Coveo Atomic into the Angular components of an SAP Commerce Cloud composable storefront.
This article shows how to replace the default components of the SAP Commerce Cloud composable storefront. As the default components already exist in the back end, you don’t need to do anything in the Backoffice Administration Cockpit. You need to update the front end only. |
Adjust the app to use Coveo
To use Coveo-powered search in your project, perform the following steps.
-
In the root of your Angular application, open the
tsconfig.json
file and update thecompilerOptions
object with the following:"compilerOptions": { // ... "allowSyntheticDefaultImports": true },
-
Install the Atomic Angular package:
npm i @coveo/atomic-angular
-
Move the Atomic static assets to the
src
directory of your app and update theangular.json
file accordingly. -
To add basic styling, include the Default Coveo Theme.
-
To be able to use the Atomic Angular components, open the
src/app/app.module.ts
file and import theAtomicAngular
module.
Update the main component
-
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', organizationId: 'orgnameplaceholder', }) .then(() => { const engine = searchInterface.engine; if (engine) { const fieldActions = loadFieldActions(engine); engine.dispatch(fieldActions.registerFieldsToInclude([ 'ec_brand', 'ec_category', 'ec_image', 'ec_price' ])); searchInterface.executeFirstSearch(); } }); } }
Specifies credentials for the target Coveo organization. See Authenticate via search token and Use API key authentication with the Search API. Specifies what custom fields to use in the UI. -
By default, the
src/app/app.component.html
contains only one component:<cx-storefront></cx-storefront>
This component is the entry point of the SAP Commerce Cloud composable storefront. To add a search interface to the storefront, you need to wrap it inside the
atomic-search-interface
component. Also, you need to add an Angular template for every Atomic component you want to implement in your project. For example, you can add aatomic-search-box
component:<atomic-search-interface> <cx-storefront></cx-storefront> </atomic-search-interface> <ng-template cxOutletRef="SearchBoxComponent"> <app-coveo-search-box></app-coveo-search-box> </ng-template>
cxOutletRef is the name of the default component you want to replace.
To find out the name of the default component, you need to:
|
For example, the default search box component is called SearchBoxComponent
:
You can also replace a default component by updating the storefront’s global configuration. See provideConfig in the SAP Commerce Cloud documentation. See the example of this method below, in the next section. |
Build a search box module
Now that you imported and initialized Coveo Atomic, you can use Atomic components to build a UI.
-
Create a
coveo-search
module:ng g module coveo-search
-
Open the created
src/app/coveo-search/coveo-search.module.ts
file and importAtomicAngularModule
:// other imports import { AtomicAngularModule } from '@coveo/atomic-angular'; @NgModule({ declarations: [], imports: [CommonModule, AtomicAngularModule] }) export class CoveoSearchModule {}
-
Next, within your new module, create a
coveo-search-box
component:ng g component coveo-search/coveo-search-box
This imports the
CoveoSearchBoxComponent
component and adds it into your module’sdeclarations
section. You may also want to specify the component in theexports
section, so that you can use it in other modules in the future.Example// other imports import { CoveoSearchBoxComponent } from './coveo-search-box/coveo-search-box.component'; @NgModule({ declarations: [CoveoSearchBoxComponent], imports: [CommonModule, AtomicAngularModule], exports: [CoveoSearchBoxComponent] })
Another way to replace componentsIf you decided not to update
src/app/app.component.html
to replace the default components, you can do the replacement via provideConfig.For example, to replace
SearchBoxComponent
, open thesrc/app/coveo-search/coveo-search.module.ts
file and add theproviders
section to the@NgModule
decorator:@NgModule({ declarations: [CoveoSearchBoxComponent], imports: [CommonModule, SearchBoxModule, AtomicAngularModule], exports: [CoveoSearchBoxComponent], providers: [ provideConfig({ cmsComponents: { SearchBoxComponent: { component: CoveoSearchBoxComponent, }, }, }), ], })
-
Update the
src/app/coveo-search-box/coveo-search-box.component.html
template:<div class="custom-search"> <atomic-layout-section section="search"> <atomic-search-box> <atomic-search-box-recent-queries></atomic-search-box-recent-queries> <atomic-search-box-query-suggestions></atomic-search-box-query-suggestions> </atomic-search-box> </atomic-layout-section> </div>
Build a search results module
The default search results component is called SearchResultsListComponent
.
To replace it with an Atomic component, perform the similar steps as for the search box component above.
-
Update the
src/app/app.component.html
file to replace that component:// ... // previously added components <ng-template cxOutletRef="SearchResultsListComponent"> <app-coveo-search-list></app-coveo-search-list> </ng-template>
-
Create a
coveo-search-result
module and thecoveo-search-list
component within it. -
Update the
src/app/coveo-search-list/coveo-search-list.component.html
template file:<div class="custom-search-results"> <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> </div>
Build a facet module
The default component for facets and filters is called ProductRefinementComponent
.
To replace it with an Atomic component, perform the similar steps as shown in the previous section.
-
Update the
src/app/app.component.html
file to replace that component:// ... // previously added components <ng-template cxOutletRef="ProductRefinementComponent"> <app-coveo-search-facet></app-coveo-search-facet> </ng-template>
-
Create a
coveo-search-result-refinement
module and thecoveo-search-facet
component within it. -
Update the
src/app/coveo-search-list/coveo-search-facet.component.html
template file:<div class="custom-search-facets"> <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> </div>
Test the application
-
To launch the application locally, run the
yarn start
command. The application will open in the browser, at thehttp://localhost:4200
address by default. -
You should now have an 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, or click the results.
To see search results, make sure that your Coveo organization already has data indexed from an SAP Commerce Cloud instance. |
Sample implementation
To see a more advanced implementation, examine the Coveo Barca demo.