Friday, June 22, 2018

Sitecore Experience Commerce - Remove Commerce Experience Accelerator JavaScript

Out of the box, if you have a site running Sitecore Experience Commerce (even with a completely custom theme) some JavaScript will get added to the page. This happens if you are using AssetLinksGenerator.GenerateLinks to give you the required CSS and JS to output on the page.

Theses scripts (as on update 1) appear as:
<script src="/Scripts/Commerce/Services/cxa.services.dom.observer.js"></script>
<script src="/Scripts/Commerce/Services/cxa.services.messaging.js"></script>
<script src="/Scripts/Commerce/Services/cxa.services.ajax.js"></script>
<script src="/Scripts/Commerce/Services/cxa.common.productselection.js"></script>
<script src="/Scripts/Commerce/Services/cxa.common.productprice.js"></script>
<script src="/Scripts/Commerce/Services/cxa.services.cart.context.js"></script>
<script src="/Scripts/Commerce/Core/cxa.core.application.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.productlistsorting.js"></script>
<script src="/Scripts/Commerce/Core/cxa.core.component.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.orders.model.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.models.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.productlistitemsperpage.js"></script>
<script src="/Scripts/Commerce/Core/cxa.core.startup.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.recent-orders.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.order-history.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.addtocart.js"></script>
<script src="/Scripts/Commerce/Feature/Checkout/cxa.feature.checkout.address.model.js"></script>
<script src="/Scripts/Commerce/Core/cxa.core.form.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.addtocart.productselection.handler.js"></script>
<script src="/Scripts/Commerce/Feature/Checkout/cxa.feature.checkout.delivery.model.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.lines.model.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.catalog.productprice.model.js"></script>
<script src="/Scripts/Commerce/Feature/Checkout/cxa.feature.checkout.billing.model.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.lines.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.catalog.productprice.js"></script>
<script src="/Scripts/Commerce/Feature/Checkout/cxa.feature.checkout.review.model.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.total.js"></script>
<script src="/Scripts/Commerce/Feature/Checkout/cxa.feature.checkout.delivery.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.total.model.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.catalog.productinventory.model.js"></script>
<script src="/Scripts/Commerce/Feature/Checkout/cxa.feature.checkout.billing.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.promotion.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.catalog.productinventory.js"></script>
<script src="/Scripts/Commerce/Feature/Checkout/cxa.feature.checkout.review.js"></script>
<script src="/Scripts/Commerce/Feature/Cart/cxa.feature.cart.promotion.model.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.catalog.productvariant.model.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.catalog.productvariant.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.productfacets.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.productlist.js"></script>
<script src="/Scripts/Commerce/Feature/Minicart/cxa.feature.minicart.model.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.productlist.model.js"></script>
<script src="/Scripts/Commerce/Feature/Minicart/cxa.feature.minicart.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.promotedproducts.js"></script>
<script src="/Scripts/Commerce/Feature/Catalog/cxa.feature.promotedproducts.model.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.registration.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.login.js"></script>
<script src="/Scripts/Commerce/Feature/LanguageSelection/cxa.feature.language.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.forgotpassword.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.changepassword.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.profileeditor.js"></script>
<script src="/Scripts/Commerce/Feature/MessageSummary/cxa.feature.messageSummary.model.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.address.list.js"></script>
<script src="/Scripts/Commerce/Feature/MessageSummary/cxa.feature.messageSummary.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.address.list.model.js"></script>
<script src="/Scripts/Commerce/Feature/Navigation/cxa.feature.navigationbar.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.address.editor.js"></script>
<script src="/Scripts/Commerce/Feature/Account/cxa.feature.address.editor.model.js"></script>
If you don't require any of this JavaScript, they can be stopped from being output by patching out the logic with the following configuration patch file.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <pipelines>
            <assetService>
                <processor type="Sitecore.Commerce.XA.Foundation.Common.Pipelines.AssetService.AddJavaScript, Sitecore.Commerce.XA.Foundation.Common">
                    <patch:delete />
                </processor>
            </assetService>
        </pipelines>
    </sitecore>
</configuration>
Appears to save quite a few requests, which should speed up page load times as well.

Tuesday, June 19, 2018

Sitecore Experience Commerce - Catalog Item of the Storefront catalog Configuration cannot be found

When viewing a Sitecore Experience Commerce shop on the Storefront (content delivery node). The following error was appearing:
Catalog Item of the Storefront catalog Configuration cannot be found.
The code appeared to be breaking when selecting a catalog node which appeared under the Catalogs item in the tree (/sitecore/Commerce/Catalog Management/Catalogs). I confirmed this item present in the web/master databases as well as in the relevant search index.

This issue was resolved by enabling the Sitecore.Commerce.Engine.DataProvider.config configuration file in the App_Config/Include/Y.Commerce.Engine folder. In our case this did not appear to be enabled in Azure PAAS with the ARM templates.

Sitecore Experience Commerce - Queries to debug whats in a search index

When debugging an issue with the front-end (storefront) site in a Sitecore Experience Commerce instance, it often becomes necessary to see what is in the search index. As an example I have had to check if a given category is appearing along with various sellable items which should appear inside it.

There is a difference on the query if you are using SOLR or Azure Search and I have provided both examples.

Index structure

It's worth noting that in an experience commerce instance there are several indexes which may need to be investigated and they each server as different sources of truth.
  • CatalogItemsScope - this index is used by the commerce engine role(s) along with the business tools for commerce.
  • mysite_web_index - used by the management (CM) servers.
  • fsni_master_index - used by the delivery servers (CD) to drive the front-end (storefront).
Note that index names may slightly vary based on your implementation.


To query SOLR

To query a SOLR index, you can open up the web administration, select the relevant index (purple box below), submit your query (red box below) and see if there are results (blue box below).

Querying commerce data in SOLR

To query Azure Search

To query an Azure Search index, you simply open the index in the Azure portal and use the search explorer to submit a query (red box below) and view any results (blue box below).

Querying commerce data in Azure Search

Categories

The following queries can be used to query a given category and the category ID can be obtained from the business tools.

Category ID visible in the business tools
In CatalogItemsScope - commerce engine index
Azure Search
"Entity-Category-MyCatalog-Bread Rolls  Buns"&searchFields=entityid
SOLR
entityid:"Entity-Category-MyCatalog-Bread Rolls  Buns"
In web/master indexes- Sitecore website
Azure Search
"Entity-Category-MyCatalog-Bread Rolls  Buns"&searchFields=catalogentityid
SOLR
catalogentityid_t:"Entity-Category-MyCatalog-Bread Rolls  Buns"

By commerce entity type

When debugging what commerce data is actually in the index, it's often handy to search based on the commerce entity type. Examples of types which I query on are:
  • SellableItem
  • Category
  • Catalog
In web/master indexes- Sitecore website
Azure Search
"SellableItem"&searchFields=commercesearchitemtype
SOLR
commercesearchitemtype_t:"SellableItem"

Conclusion

The above post gives some details on which search index you would want to query to debug a given issue along with some query samples for both Azure Search and SOLR. These queries can then be modified to query other fields (such as the Sitecore ID visible in the content editor interface. 

Wednesday, June 13, 2018

Sitecore Experience Commerce - Commerce service Error code Forbidden

On the content management server of a Sitecore enthronement containing Experience Commerce 9 (update 1), the following was appearing in the logs when attempting to refresh the commerce cache:
An error occured while trying to contact the Commerce Service. Error code Forbidden
I tried two things and one of which (or the combination) was able to resolve this error:
  1. In the show config page (site/admin/showconfig.aspx) the configuration where the URLs for the shops/ops service had line spacing. I moved these onto one line.
  2. On the commerce engine shops environment I opened the config.json file and added the URL for the content management server to the AllowedOrigins array.
Please leave a comment below, if you have found other causes for this error.

Sitecore - the controller for path was not found or does not implement IController

When attempting to load a Sitecore page via a content delivery server, the following error occurred:
Server Error in '/' Application.
The controller for path '[PageUrl]' was not found or does not implement IController.
Description: An unhandled exception occurred.
Exception Details: Sitecore.Mvc.Diagnostics.ExceptionWrapper: The controller for path '[PageUrl]' was not found or does not implement 
The cause of the error was a rendering on the page having an incorrect controller set. Fixing this was able to allow the page to load as expected. 

Saturday, June 2, 2018

Sitecore - errors occurred while attempting to load the app

When attempting to load a Sitecore 9 instance the following error would show:
The following errors occurred while attempting to load the app.
- No assembly found containing an OwinStartupAttribute.
- The discovered startup type 'Sitecore.Owin.Startup, Sitecore.Owin, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null' conflicts with the type 'SolrNet.Startup, SolrNet, Version=0.4.0.2002, Culture=neutral, PublicKeyToken=null'. Remove or rename one of the types, or reference the desired type directly.
To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of "false" in your web.config.
To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.
Sitecore startup error with OWN and SOLR
This was caused by a rogue web project deploying an empty web.config and overwriting the Sitecore default. By replacing the web.config file with the correct version, the error stopped occurring.