Upgrade to v3

As of v3, it's now possible to consume @salesforce/retail-react-app updates by adding it as an npm dependency and enabling template extensibility in your project.

This guide covers how to update a PWA Kit project from v2.7.x to v3.0.0.

We’ve added lots of new features to PWA Kit v3, including:

⚛️ Required:

  • getProps breaking change
  • Major library updates, including support for React 18, Node 18, Chakra 2, and more

🔨 Optional: Template extensibility — Greatly reduce your project's code footprint and reduce development toil, cost of ownership, and future upgrade headaches. For more details, see the Template Extensibility guide!

🪝 Optional: @salesforce/commerce-sdk-react "hooks" integration — Decouples API calls from a project's implementation, allows API calls to be upgraded as an npm library dependency, and brings along many of the great features (including state management, and others) via TanStack Query. See the the Commerce SDK React docs to get started!

The PWA Kit SDKs have been moved to the @salesforce NPM organization. To upgrade to v3, install the new packages and replace all import statements for the following packages:

  • pwa-kit-react-sdk -> @salesforce/pwa-kit-react-sdk@^3
  • pwa-kit-runtime -> @salesforce/pwa-kit-runtime@^3
  • pwa-kit-dev -> @salesforce/pwa-kit-dev@^3
  • pwa-kit-create-app -> @salesforce/pwa-kit-create-app@^3
  • retail-react-app -> @salesforce/retail-react-app@^3

As of v3.0.0, PWA Kit introduces a new data fetching strategy withReactQuery. This strategy uses the react-query library and allows you to write React hooks to fetch data isomorphically. Unlike with getProps, you no longer need to duplicate the data fetching logic for the client side and the server side. In this version, by default, @salesforce/retail-react-app uses @salesforce/commerce-sdk-react which is powered by react-query.

  • You can use both withReactQuery and withLegacyGetProps at the same time.
  • getProps and shouldGetProps were removed from the default template of pages of the Retail React App, but aren’t deprecated. Long-term support for these methods remains.

Change dependencies in package.json as shown below. Remove @chakra-ui/system from peerDependencies and include it under dependencies or devDependencies.

Update engines in package.json to support Node 18 and npm 9.

Reinstall dependencies for your project with npm i.

When migrating from v2.7.x to v3.x you can choose whether you want to use Template Extensibility. To benefit from it, you must import at least one file from @salesforce/retail-react-app (or another extendable template in the future).

From there, consider how many files you have modified in from the original project that you generated via npx pwa-kit-create-app@2.x. Some customers have large numbers (perhaps hundreds) of files, but even then, a significant number can be unmodified. Those unmodified files are a good candidate for importing from @salesforce/retail-react-app, but we recommend doing this process carefully and gradually. Many files in @salesforce/retail-react-app are similar but have been changed from their previous state in v2.x of the PWA Kit Retail React App. In particular, the @salesforce/commerce-sdk-react integration (migration details covered in more detail later) has caused a large number of files to change in terms of their imports as well as their file structure, removing the entire commerce-api directory from the app, as a starting point that is in itself a significant change.

When migrating a project to use template extensibility, please note that version 2.x of the PWA Kit SDKs and projects generated via npx pwa-kit-create-app@2.x do not have a dependency on @salesforce/commerce-sdk-react whereas the newer code @salesforce/retail-react-app@^1.x makes heavy use of this library, which touches and changes many files. To get a sense of the magnitude of the changes, you can compare release-2.7.xrelease-3.0.x in this Github diff https://github.com/SalesforceCommerceCloud/pwa-kit/compare/release-2.7.x...release-3.0.x?diff=unified#files_bucket and search for @salesforce/commerce-sdk-react and take note of all the additions that add this import.

If your app attempts to share code with version 2.x (which includes the app/commerce-api directory), you risk adding unnecessary code to your bundle where that code exists (in two very different forms) in both the commerce-api folder and the @salesforce/commerce-sdk-react npm module.

As of v3.0.0, PWA Kit uses a different fetch strategy withReactQuery. This strategy leverages the react-query library and enables queries in the SSR rendering pass. The @salesforce/retail-react-app uses @salesforce/commerce-sdk-react which is powered by react-query.

In order for hooks to work on the server side, you need to wrap your AppConfig component with the new higher-order component withReactQuery.

As part of the migration to ReactQuery as the default fetch strategy, @salesforce/retail-react-app@^1 a change is required to ensure legacy getProps() calls continue to work.

When you complete the dependency upgrades described above you may encounter issues in your project related to the below libraries. In the sections below we propose solutions for resolving these issues. The particulars of your project will vary and proposed solutions should be treated as guidelines and not absolute rules.

For the react-hook-form migration, read the react-hook-form official doc here. In the PWA project, there are two places that require changes:

  1. Move form errors object into one more layer of destructing for hooks in app/components/forms/ as the errors object has been moved into the formState object.
  1. Move the render props in Controller into the field prop. Render's callback signature returns an object that contains field and fieldState.

As of React 18, hydration warnings are surfaced as errors instead of warnings as they had been in React 17. Some code updates were required to suppress these potential errors that prevent the application from building when there are hydration errors. It is essential to fix these errors to ensure the app can render isomorphically. This error occurs because there is a mismatch between server or client. If a component or a page happens to render conditionally, you must make sure that the hydration is finished before rendering any client-specific code.

In your project, create a utility function to determine if the hydration has finished. you can use a built-in variable provided by window.__HYDRATING__ in pwa-kit-react-sdk.

If your project uses components and APIs from the @chakra-ui/react library that are different than the Retail React App template, review the official Chakra 2 migration docs.

To support Chakra 2, there are a few files that require updates for projects based on the Retail React App template:

Remove allowToggle in the Accordion component because allowMultiple and allowToggle can't be used at the same time in Chakra 2.

In the Footer component, importing StylesProvider directly from @chakra-ui/react is deprecated. You must create it via createStylesContext('Footer') instead.

Set up userEvent before calling any action, and await the action in unit tests that uses userEvent because in React testing library v14.0.0, all the user actions are async, and it requires calling setup before performing user actions.

For example:

For more details, see the official docs for userEvent from testing-library.

Alternatively, to avoid repetitively calling setup()in many unit tests, you can set up youruserEvent in app/utils/test-util.js right before rendering the test component and return it along with render results so that the test can perform the user actions without having to call setup()`.

In jest-setup, there is a mock dependency that can throw an error about TextDecoder being undefined in jest-setup.js. Add the following to jest-setup.js:

When migrating from version 2.x of the PWA Kit SDKs or projects generated via npx pwa-kit-create-app@2.x, the @salesforce/commerce-sdk-react code has been significantly refactored to remove the app/commerce-api/ directory. Instead of those files handling API request and acting as an SDK, @salesforce/commerce-sdk-react supersedes that functionality. The v3 release of the SDKs correlates with the first release of @salesforce/retail-react-app@^1.x because the SDKs use this library a lot.

The implementation of @salesforce/commerce-sdk-react changes many files in the Retail React App. To get a sense of the size of the changes, compare release-2.7.x to release-3.0.x in this GitHub diff and search for @salesforce/commerce-sdk-react. In the diff, take note of all the additions that include this import.