v2.0.0 release notes

In his release, we have:

Core upgrade

In this release, we have upgraded our core packages (such as @vue-storefront/core) to their latest versions. We suggest doing the same in your project.


  "name": "@vsf-enterprise/sapcc-theme",
  "dependencies": {
-    "@vue-storefront/http-cache": "^2.5.4",
-    "@vue-storefront/middleware": "^2.5.4",
-    "@vue-storefront/nuxt": "^2.5.4",
+    "@vue-storefront/http-cache": "^2.7.5",
+    "@vue-storefront/middleware": "^2.7.5",
+    "@vue-storefront/nuxt": "^2.7.5",

Reworked middleware.config.js file

In this release, we have introduced some breaking changes in the middleware.config.js file. We have:

  • removed the mediaHost property since it is only used inside the Nuxt application now,
  • removed the baseStore property since it is not needed anymore,
  • renamed baseStoreId to baseSiteId,
  • renamed currency to defaultCurrency and moved it into configuration.api object,
  • renamed lang to defaultLanguage and moved it into configuration.api object,
  • moved OAuthServer object outside of configuration.api and renamed it to OAuth,
  • moved clientId and clientSecret into configuration.OAuth,
  • renamed OAuthServer.host to OAuth.uri,
  • renamed OAuthServer.authenticationEndpoint to OAuth.tokenEndpoint,
  • renamed OAuthServer.authenticationTokenRevokeEndpoint to OAuth.tokenRevokeEndpoint.

You can review the new shape of the middleware.config.js file in the Configuration section.

If you have created any custom extensions in your project, review and update all logic depending on the configuration extracted from the context.

export const customExtension = {
  name: 'my-custom-extension',
  extendApp(context) {
-   const {
-     clientId,
-     clientSecret,
-     OAuthServer: {
-       host,
-       authenticationEndpoint,
-       authenticationTokenRevokeEndpoint
-     }
-   } = context.configuration.api;
+   const { clientId, clientSecret, uri, tokenEndpoint, tokenRevokeEndpoint } = context.configuration.OAuth;   
  extendApiMethods: {
    myCustomMethod: async (context) => {
-     const { config: { api: { baseStoreId } } } = context;
+     const { config: { api: { baseSiteId } } } = context;

New useStore composable method

Up until this point, we had no dedicated composable method for fetching and storing Base Store configuration on the frontend. Fortunately, this release brings a new useStore composable method. Read the documentation to find out how to use it.

Reworked application token refreshing mechanism

In this release, we have refactored the way our API Middleware refreshes the global application token. It used to be refreshed every x seconds (where x was equal to the value of the expires_in key found in the token object returned by SAP's authorization server). From now on, it will only be refreshed whenever some request using it yields a 401 (Unauthorized) error.


We have also changed the location of the ConcurrentCallbacksReducer helper. It can now be imported from the @vsf-enterprise/sapcc-api package instead of @vsf-enterprise/sapcc.

- import { ConcurrentCallbacksReducer } from '@vsf-enterprise/sapcc';
+ import { ConcurrentCallbacksReducer } from '@vsf-enterprise/sapcc-api';

const reduceConcurrentCallbacks = new ConcurrentCallbacksReducer().reduce;

Multistore support

In this release, we have introduced support for SAP Multistore (including both multi-currency and multi-locale setup). Read our new Multistore guide and the updated Configuration guide to learn how to implement it in your project.

We also encourage you to visit our staging demo environment to see two standard SAP stores (Electronics (opens new window) and Apparel (opens new window)) served by a single Vue Storefront application.

Dynamic category list in the header navigation

Until now, the category list in the header of our storefront was static. In this release, we have made it dynamic so that it changes at runtime (for example depending on the store currently visited SAP store). This way a single storefront can display different category navigations for Electronics and Apparel stores.

Theme updates:

  • ~/components/AppHeader.vue,
  • ~/components/HeaderNavigation.vue.

Electronics store

Electronics store dynamic categories

Apparel store

Apparel store dynamic categories

This release introduces a new cookieOptions property in middleware.config.js. It allows for configuring options of the vsf-sap-token cookie coming from our API Middleware as a result of authentication and token refresh requests. Read the updated Configuration guide to find out more.

Removed unused plugins and middlewares from the storefront

While working on the Multistore support, we removed a few redundant storefront plugins and middlewares. Their responsibilities have been taken over (mostly) by a new loadStore plugin installed in your project automatically by the @vsf-enterprise/sapcc package.

After upgrading to the latest version of our SAP Commerce Cloud integration, feel free to delete these files in your project:

  • ~/plugins/inject-store-configuration.js,
  • ~/plugins/add-currency-to-request.js,
  • ~/middleware/check-config.ts,
  • ~/middleware/is-authenticated.js.

Changed the default response fields of getProductReferences

By default, the majority of our API Middleware endpoints send requests to SAP Commerce Cloud with fields set to FULL. The getProductReferences endpoint has been an exception to this rule. We have changed that in this release.

If you've been using the useProductReferences().search() (opens new window) method, you don't have to pass fields: FULL to it anymore:

import { useProductReferences } from '@vsf-enterprise/sapcc';

setup() {
  const { search } = useProductReferences();

  onMounted(async () => {
-   await search({ productCode: '1', fields: 'FULL' });
+   await search({ productCode: '1' });

The same thing applies to the getProductReferences endpoint called directly:

import { useVSFContext } from '@vue-storefront/core';

setup() {
  const { $sapcc } = useVSFContext();

  onMounted(async () => {
-   const references = await $sapcc.api.getProductReferences({ productCode: '1', fields: 'FULL' });
+   const references = await $sapcc.api.getProductReferences({ productCode: '1' });

Updated ProductReferenceTypeEnum

Another change related to the getProductReferences endpoint is an update of the ProductReferenceTypeEnum. We have turned it from a numeric enum (opens new window) into a string enum (opens new window).

import { useProductReferences } from '@vsf-enterprise/sapcc';
import { ProductReferenceTypeEnum } from '@vsf-enterprise/sapcc-api';

setup() {
  const { search } = useProductReferences();

  onMounted(async () => {
-   await search({ productCode: '1', type: ProductReferenceTypeEnum[0] });
+   await search({ productCode: '1', type: ProductReferenceTypeEnum.ACCESSORIES });

Exported the GetCategoryProps interface from @vsf-enterprise/sapcc-api

The GetCategoryProps interface used by the getCategory endpoint can now be imported from the @vsf-enterprise/sapcc-api package:

import { GetCategoryProps } from '@vsf-enterprise/sapcc-api';

setup() {
  const props: GetCategoryProps = { id: 'collections' };

Allow calling getCatalogVersion API endpoint without props

From now on, you can call the getCatalogVersion endpoint without any props as they've become purely optional.

import { useVSFContext } from '@vue-storefront/core';

setup() {
  const { $sapcc } = useVSFContext();

  onMounted(async () => {
-   const catalogVersion = await $sapcc.api.getCatalogVersion({});
+   const catalogVersion = await $sapcc.api.getCatalogVersion();

Allow modifying fields of all sub-requests of getProductSearchPageData

getProductSearchPageData endpoint returns all of the data you need to build a Product Listing Page. Under the hood, it composes responses returned by two other API methods: searchProduct and getCatalogVersion.

From now on, GetProductSearchPageDataProps allow you to pass arguments to both these methods separately to modify their behavior and - in turn - the response returned by the getProductSearchPageData endpoint. Refer to the interface definition to find out more about available properties.

Moved all logic behind building SAP product queries to the searchProduct endpoint

Until now, the logic behind build SAP product queries has been split between the searchProduct endpoint and the useProductSearch().search() method. In this release, we have moved all of that logic to the searchProduct endpoint. As a result, new properties have been added to the ProductSearchProps interface.