Phased Headless Rollouts

Phased rollouts of headless technologies are now possible for users of the Storefront Reference Architecture (SFRA) and SiteGenesis. For example, you can deploy a bold new experience for product pages using PWA Kit and keep the checkout flow on SFRA until the next phase of your headless transition. This phased approach helps you get started sooner and minimizes disruptions along the path to headless.

This guide describes how to use session bridging and routing rules to enable PWA Kit to power one set of pages and SFRA to power another set of pages with a seamless user experience.

To learn more about using Einstein Activities in a phased headless context, see Einstein Activities for Phased Headless Rollouts.

The instructions in this guide describe how to combine PWA Kit and SFRA flows, but the same instructions can be adapted for SiteGenesis.

Enabling shoppers to seamlessly navigate between pages powered by different storefront architectures requires using a technique called session bridging. Session bridging uses cookies to share shopper refresh tokens and session tokens across different systems.

The key to unlocking session bridging is the Shopper Login and API Access Service (SLAS), a new standards-based solution for authentication and authorization that can be accessed through HTTP requests. Shopper authentication with SLAS is based on OpenID Connect and authorization for Commerce Cloud’s Shopper APIs is based on OAuth 2.

When a shopper browses a headless storefront, you use SLAS to request an access token and a refresh token and store them as cookies on the shopper’s browser. You can set the cookie with the HTTP set-cookie header or with client-side JavaScript. As the shopper transitions from an SFRA page to a PWA Kit page (or vice versa), the cookie with the refresh token is sent along with the HTTP request and the storefront code can use the refresh token to log the user in.

The first step in creating a phased headless rollout is to set up your PWA Kit application to use SLAS (if you haven’t already). Follow the instructions in our Set Up API Access guide.

To enable a phased headless rollout with SFRA, you must install the SLAS plug-in cartridge. Complete installation instructions are provided in the README for the cartridge.

In addition to session bridging, the SLAS plug-in cartridge allows you to implement other shopper-friendly features, such as 90-day user sessions and basket persistence.

Important Considerations for SLAS Cartridge Users

The plugin_slas cartridge makes multiple calls to various APIs, which can impact storefront performance. Before adding the cartridge to a production storefront, compare the performance of your storefront with and without the cartridge to decide if it’s right for you.

The cartridge also introduces a redirect under the following conditions:

  • When a shopper doesn’t have a session cookie yet
  • When a shopper’s session cookie has expired
  • When a search engine is indexing your site

Currently, the cartridge only replaces direct login to the B2C Commerce system where the credentials are stored within Salesforce.

When used with the wishlists plugin, guest wishlists are not transferred on login to the registered user.

Before using the cartridge, review the issues page on GitHub.

Because the SLAS plug-in cartridge is designed for SFRA, additional code must be written to use it with SiteGenesis. A SiteGenesis implementation can leverage code from the cartridge at various points in the shopper authentication and authorization flows.

Because the cartridge uses the B2C Commerce Web Service Framework to handle SLAS API calls, a SiteGenesis implementation can make requests to the web services implemented by the cartridge. These web services include guest login, registered customer login, token refresh, logout, and merging the guest basket. The cartridge also implements a service to merge API sessions and storefront sessions.

A SiteGenesis implementation can also use a custom hook (app.plugin.slas.login) to implement login for guests and registered users with SLAS. Examine the custom code in the cartridge’s onSession hook in dw.system.request.onSession to see how it replaces the Script API with SLAS for shopper login.

To make session bridging possible with PWA Kit, you must modify the code in commerce-api/auth.js that handles API authorization to use cookies instead of local storage.

If your PWA Kit project was generated with version 1.5.0 or later of the Retail React App template, you can uncomment this line of code in auth.js, and no further changes to the file are required.

For projects generated before version 1.5.0, you must make several changes to commerce-api/auth.js. To save you time, we’ve created an alternate version of the file with all the changes in place and made it available on GitHub through a public gist.

The authorization flow starts with the refresh token. If the refresh token cookie is available, the PWA Kit app exchanges the refresh token for an access token. Otherwise, the app starts an authorization code grant flow, as defined by the OAuth 2.1 standard. It also follows the proof key for code exchange (PKCE) flow.

When the new access token and new refresh token are granted by SLAS, the app stores them in cookies. Then the app makes a POST request to OCAPI’s create session endpoint (/session). This endpoint creates a session that is used by SFRA. The app stores the session token in a cookie.

Cookies created by the PWA Kit app:

  • cc-nx-g - SLAS guest shopper refresh token
  • cc-nx - SLAS registered shopper refresh token
  • token - SLAS access token
  • dwsid - Demandware session id

The following diagram illustrates the modified authorization flow for PWA Kit:

Associated diagram -large

You must modify the code in commerce-api/auth.js that calls the session-bridge API after shopper login.

If your PWA Kit project was generated with version 2.7.1 or later of the Retail React App template, you can uncomment this line of code in auth.js, and no further changes to the file are required.

For projects generated before version 2.7.1, you must make couple changes to commerce-api/auth.js. To save you time, we’ve created an alternate version of the file with all the changes in place and made it available on GitHub through a public gist.

To ensure a seamless user experience during a phased rollout, you need a way to route traffic to two different origins: the Managed Runtime environment and your B2C Commerce instance. This traffic routing can be handled by a content delivery network (CDN).

Imagine the following scenario:

You have an existing SFRA storefront running on You know the benefits of headless architecture and want to leverage PWA Kit to deliver performant and engaging experiences. At the same time, you want to minimize risk to the schedule, so you choose a phased approach to rolling out your PWA Kit storefront.

You configure the CDN to send page request at the top of the funnel to PWA Kit: home page (/), the category listing page (/category), and the product details page (/product). These PWA Kit pages are deployed to a Managed Runtime environment running on When the shopper decides to make a purchase, the CDN redirects the shopper to the existing SFRA checkout page running on

To handle traffic routing, you can choose the embedded CDN (eCDN) solution from Salesforce (and powered by Cloudflare) or choose a CDN from a different vendor.

To use eCDN to route traffic to Managed Runtime, use the Commerce API endpoint createMrtRules.

The API supports routing traffic to Managed Runtime using Cloudflare Rule Expressions. It supports a subset of the available fields in the Rules language. The following fields are supported:

  • to match with the host name
  • http.request.uri.path to match against the request path
  • http.request.uri to match against both the request path and query string
  • http.cookie to match against cookies

You can request 100 individual rules per instance on proxy zones and 100 individual rules in total shared between dev/prod instances on legacy zones.

  • The eCDN is only available for prod and dev instances and not available for sandbox or ODS instances.
  • Staging instances must be onboarded to eCDN using the eCDN API. For more information, see Configure eCDN for Staging on the B2C Commerce Infocenter and this article from the Rhino Inquisitor blog.
  • The eCDN doesn’t support routing based on geolocation.

To help design your origin rules, gather a comprehensive list of routes for PWA Kit pages. For a PWA Kit project based on the Retail React App template, the routes are listed in app/routes.jsx. Because the server-side rendering system for PWA Kit uses internal routes for proxies and static assets, you must also include /mobify/* in the routing rules.

For our example scenario, the following routes must be configured in your CDN:

Build an origin rule that includes all the PWA Kit routes on your list to forward the request to the Managed Runtime environment ( in our example scenario).

The following diagram shows the eCDN configuration for the example scenario that we described earlier:

Associated diagram -medium

By default, the Retail React App template for PWA Kit projects has a different URL routing pattern than SFRA. For example, the URL path for a product detail page in the Retail React App is /products/{productId}. With SFRA, the pattern is /{categoryId}/{productId}.

We recommend that you change the routing patterns in your PWA Kit storefront to match your SFRA site. If you are unable to match the URL patterns for a specific page (like the product listing page when the category ID is not available in the URL), you can use the Redirect Cartridge to set up redirects that close the gap. Complete installation instructions are provided in the README for the cartridge.

To complete the setup process for a phased headless rollout, you must make a few more changes to your PWA Kit project.

By default, PWA Kit uses the History API for navigation. When a shopper clicks a link made with React Router’s <Link> component, it triggers a soft navigation to the component matching the path in the route object defined in app/routes.jsx. To link to a non-PWA Kit page (one powered by SFRA, for example), you must remove any route matching the URL pathname from app/routes.jsx.

For example: remove checkout from the routes array. Remove-checkout-route

Lastly, update the PWA catch-all route (/*) in app/routes.jsx. Replace the PWA <PageNotFound /> component with a redirect to the default origin.