SAP Spartacus - Overriding the default cx-storefront

2 min read

In this post we’ll be replacing the out of the box [cx-storefront , cx-header] component with our own custom storefront and customize according to our requirements.

We’ll be creating the module and the component with name vr-storefront and vr-header components.

  1. Module and component of [vr-storefront]
 ng g m spartacus/vr-storefront
 ng g c spartacus/vr-storefront --export
  1. Module and component of [vr-header]
 ng g m spartacus/vr-storefront/vr-header
ng g c spartacus/vr-storefront/vr-header --export

Replacing the cx-storefront with the vr-storefront component. In this we will extend the VrStorefrontComponent from the StorefrontComponent like this :

Filename : vr-storefront.component.ts

import { Component, OnInit } from "@angular/core";
import { StorefrontComponent } from "@spartacus/storefront";

@Component({
selector: "vr-storefront",
templateUrl: "./vr-storefront.component.html",
styleUrls: ["./vr-storefront.component.scss"],
})
export class VrStorefrontComponent extends StorefrontComponent {}

The VrStorefrontModule should look like this right now :

Filename : vr-storefront.module.ts

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { VrStorefrontComponent } from "./vr-storefront.component";
import { RouterModule } from "@angular/router";
import {
GlobalMessageComponentModule,
OutletModule,
OutletRefModule,
PageLayoutModule,
PageSlotModule,
KeyboardFocusModule,
SkipLinkModule,
} from "@spartacus/storefront";
import { VrHeaderModule } from "../vr-header/vr-header.module";

@NgModule({
declarations: [VrStorefrontComponent],
imports: [
CommonModule,
RouterModule,
GlobalMessageComponentModule,
OutletModule,
OutletRefModule,
PageLayoutModule,
PageSlotModule,
KeyboardFocusModule,
SkipLinkModule,
VrHeaderModule,
],
exports: [VrStorefrontComponent],
})
export class VrStorefrontModule {}

Finally, import the VrStorefrontModule in the AppModule. Then replace the cx-storefront with the vr-storefront in the app.component.html. Now your storefront should work and look as it was before.

Filename : app.component.html

<!-- <cx-storefront></cx-storefront> -->
<vr-storefront></vr-storefront>

Filename : app.module.ts

@NgModule({
declarations: [AppComponent],
imports: [
//other imports goes here
VrStorefrontModule,
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}

Replacing the header with your custom one. Open the vr-storefront.component.html, and replace the header and navigation sections with the vr-header.component.html component. Here’s how your template should look

<ng-template [cxOutlet]="StorefrontOutlets.STOREFRONT" cxPageTemplateStyle>
<ng-template cxOutlet="cx-header">
<header
cxSkipLink="cx-header"
[cxFocus]="{ disableMouseFocus: true }"
[class.is-expanded]="isExpanded$ | async"
(keydown.escape)="collapseMenu()"
(click)="collapseMenuIfClickOutside($event)"
>

<!-- Added default class and section to match the same UI-->
<vr-header section="header" class="header"></vr-header>
</header>
<cx-page-slot position="BottomHeaderSlot"></cx-page-slot>
<cx-global-message
aria-atomic="true"
aria-live="assertive"
>
</cx-global-message>
</ng-template>

<main cxSkipLink="cx-main" [cxFocus]="{ disableMouseFocus: true }">
<router-outlet></router-outlet>
</main>

<ng-template cxOutlet="cx-footer">
<footer cxSkipLink="cx-footer" [cxFocus]="{ disableMouseFocus: true }">
<cx-page-layout section="footer"></cx-page-layout>
</footer>
</ng-template>
</ng-template>

Implementing the header component. We want some parts of our header to be editable via CMS, like links or the navigation bar. In order to do so, we’ll put the cx-page-slot component in these places. The slot component will render components assigned to a given slot in the CMS.

Here’s a sample markup for our header

Note : We can change the component mapping according to our requirements and update the cx-page-slot accordingly. In this we are showing the default slots present in the header.

Filename : vr-header.component.html

<cx-page-slot position="PreHeader"></cx-page-slot>
<cx-page-slot position="SiteContext"></cx-page-slot>
<cx-page-slot position="SiteLinks"></cx-page-slot>
<cx-page-slot position="SiteLogo"></cx-page-slot>
<cx-page-slot position="SearchBox"></cx-page-slot>
<cx-page-slot position="SiteLogin"></cx-page-slot>
<cx-page-slot position="MiniCart"></cx-page-slot>
<cx-page-slot position="NavigationBar"></cx-page-slot>

In order to make this work, we need to import the dependencies in the vr-header.module.ts. Here’s what it should look like

Filename : vr-header.module.ts

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { VrHeaderComponent } from "./vr-header.component";
import { RouterModule } from "@angular/router";
import { UrlModule, I18nModule } from "@spartacus/core";
import {
GenericLinkModule,
PageSlotModule,
SearchBoxModule,
IconModule,
MiniCartModule,
NavigationModule,
} from "@spartacus/storefront";

@NgModule({
declarations: [VrHeaderComponent],
imports: [
CommonModule,
GenericLinkModule,
PageSlotModule,
SearchBoxModule,
IconModule,
MiniCartModule,
UrlModule,
NavigationModule,
I18nModule,
RouterModule,
],
exports: [VrHeaderComponent],
})
export class VrHeaderModule {}

If you have done the setup correctly then you will be able to see something like this as shown in below screenshot :

Custom CX-STOREFRONT


Thanks for reading !!! 😊
Share this post :

SAP Spartacus - Overriding components using Outlets