Extending SXA Storefront configuration files

Abstract

Overview of SXA Storefront configuration files and examples of how to extend them.

SXA Storefront configuration files are grouped by feature area to enable extensibility so that you can customize and replace default implementations to address your requirements. In some cases, a single configuration file encompasses multiple renderings and, in other cases, a rendering has its own configuration file.

Configuration files are located in the C:\inetpub\wwwroot\<SXAStorefront>\App_Config\Include\Feature\Commerce directory and include:

  • Sitecore.Commerce.XA.Feature.Catalog.config - this configuration file contains everything to do with catalogs.

  • Sitecore.Commerce.XA.Feature.<rendering>.config - several renderings have their own configuration file including the Sitecore.Commerce.XA.Feature.Cart.config, Sitecore.Commerce.XA.Feature.Checkout.config, Sitecore.Commerce.XA.Feature.FreeGiftSelection.config, and Sitecore.Commerce.Feature.Minicart.config, and so on.

The SXA Storefront configuration files make use of dependency injection built into Sitecore and have the following extensibility points. By default, in SXA Storefront configuration files, there are four common configurations you can define and customize:

You can add additional configuration files as required.

The following code is an example of the configuration file structure.

<configuration>
    <sitecore>
        <commerce.XA>
           <models>
                <!--<Ajax calls model>---> 
                <!--<Rendering model>--->
           </models>
        </commerce.XA>
        <pipelines>
                <!--<Pipelines’ processors>--->
        </pipelines>
        <services>
                <!--<Registered services>--->
        </services>
    </sitecore>
</configuration>

The following example, taken from the Sitecore.Commerce.XA.Feature.Cart.config file, a model used in the Ajax call to get the cart lines count is defined. If you want to pass more information between the frontend and backend in the call, you create a new custom class that inherits from the original CartLinesCountJsonResult class and then you add a new custom config file that patches the default configuration to point to the custom class you defined. You may also have to update the JavaScript that performs the Ajax call and the backend method receiving the call depending on the nature of the change and the implementation.

<commerce.XA>
    <models>
<CartLinesCountJsonResult
          type="Sitecore.Commerce.XA.Feature.Cart.Models.JsonResults.CartLinesCountJsonResult, Sitecore.Commerce.XA.Feature.Cart" />
    </models>
</commerce.XA>

You can add your own MVC rendering models. In the <models> section, you define:

  • the new type for the renderingmodel

The following example, taken from the Sitecore.Commerce.XA.Feature.MiniCart.config file, defines the Minicart rendering model.

<commerce.XA>
    <models>
<MinicartRenderingModel
        type="Sitecore.Commerce.XA.Feature.Cart.Models.MinicartRenderingModel, Sitecore.Commerce.XA.Feature.Cart" />
</commerce.XA>

If you want to expand on the content exposed in an existing rendering model so that more data is available to the rendering, you need to create a new custom class that inherits from the original class – in this case, the MinicartRenderingModel class - and then add a new custom configuration file that patches the default configuration to point to the custom class you defined.

If you are extending a model consumed by a regular MVC rendering based on a Razor view, you update the view to fetch the added information. Instead of updating the default view, you clone the rendering and point it to the new custom view. By cloning the rendering, you ensure your customizations are not overwritten during product upgrades. If the rendering is based on a rendering variant, you can access the new properties on the custom model using SXA renderers. If the rendering variant uses a Scriban template, the new model properties are immediately available and accessible from the Scriban code. Just like with views, it is important you clone the rendering so that your customizations are not overwritten on product upgrade.

You can modify existing pipelines or add a custom pipeline. Each pipeline contains a series of processors. In the <pipelines> section, you define the pipeline to extend or add and then specify new or customized:

  • Processors that are part of initialization

  • Processors that are part of a specified group, like experienceAccelerator

In the following example, taken from the Sitecore.Commerce.XA.Feature.Catalog.config file, the standard SXA pipeline is InitializeGlobalFilters and the new commerce-specific processor being patched is PrepareSearchItems.

<pipelines>
      <initialize>
        <processor
          patch:before="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeGlobalFilters, Sitecore.Mvc']"
          type="Sitecore.Commerce.XA.Feature.Catalog.Pipelines.Initialize.RegisterRoutes, Sitecore.Commerce.XA.Feature.Catalog" />
      </initialize>
      <group groupName="experienceAccelerator">
        <pipelines>
          <processSearchItems>
            <processor type="Sitecore.Commerce.XA.Feature.Catalog.Pipelines.Search.PrepareSearchItems, Sitecore.Commerce.XA.Feature.Catalog" resolve="true" />
          </processSearchItems>
        </pipelines>
      </group>
    </pipelines>

Each service layer has its own interface that you can customize. A service is typically an API of some kind and, with SXA Storefront, the MVC controller for each rendering is registered as a service so that it can be customized and replaced. In the <services> section, you register the service and interface and define the lifetime services (Transient or Singleton). For each service, you specify the following:

  • serviceType - configures the interface API.

  • implementationType - implements the interface.

  • Lifetime service - determines how the service is handled. Transient lifetime services are created each time they are requested from the service container. Singleton lifetime services, on the other hand, are created the first time they are requested and every subsequent request uses the same instance.

In the following example, taken from the Sitecore.Commerce.XA.Feature.Catalog.config file, the Product Price Controller and interface are registered with Sitecore as transient.

<service>
<register
    serviceType="Sitecore.Commerce.XA.Feature.Catalog.Controllers.ProductPriceController, 
    Sitecore.Commerce.XA.Feature.Catalog"
    implementationType="Sitecore.Commerce.XA.Feature.Catalog.Controllers.ProductPriceController, 
    Sitecore.Commerce.XA.Feature.Catalog"
    lifetime="Transient" />
</service>