SAP Spartacus - Overriding the default cx-storefront
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.
- Module and component of
[vr-storefront]
ng g m spartacus/vr-storefront
ng g c spartacus/vr-storefront --export
- 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 :