---
schema_version: "1"
id: b674a53563987c301157107c340fcbd463f2a80ae1ff778c1b4e93445da5dfce
title: Template Extensibility
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/pwa-kit-managed-runtime/guides/template-extensibility.md
canonical_url: https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/template-extensibility.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 56dcc1e1df538ed5f6ec2d96d33777b30c9759e1ca6a8b9685efd0fd7d901602
products:
  - Composable Storefront
  - Salesforce APIs
---
# Template Extensibility

Template extensibility is a feature introduced in [PWA Kit v3](https://github.com/SalesforceCommerceCloud/pwa-kit/releases/tag/v3.0.0). The goal of this feature is to empower you to build PWA Kit projects more easily by customizing templates. You can customize existing base templates, such as the Retail React App, or you can [create your own](#create-a-base-template). We encourage members of the PWA Kit community to share their base templates with each other.

Template extensibility helps you modify a chosen template without having to duplicate every file within it.

**note:** Template extensibility is an optional feature. However, new projects generated after June 15, 2023 are automatically configured to use template extensibility.

## How It Works

In PWA Kit v3, a project can have a base template and an overrides directory, both of which can be configured in the project’s `package.json` file. To use template extensibility, you must declare a base template with `ccExtensibility.extends` in `package.json` and you must declare an overrides directory with `ccExtensibility.overridesDir`. (Configuration details are covered in the next section.)

A base template is an npm module that contains a fully functional PWA Kit project that has been preconfigured so that another PWA Kit project can override some of its files. Sometimes a base template is also called an "extensible app" or an "extendable app."

The overrides directory is a directory within your project where you can store files that override corresponding files in the base template.

Assume that you've already defined an override directory and defined the Retail React App as your base template. Let's say that you want to override the home page component of the Retail React App. In the Retail React App, the code for the home page component is in `app/pages/home/index.jsx` within the `@salesforce/retail-react-app` package. To override that file, you must recreate that same file in the directory declared via `ccExtensibility.overridesDir` in `package.json`. Therefore, the path for the new file is `<ccExtensibility.overridesDir>/app/pages/home/index.jsx`.

Now, whenever `index.jsx` is imported into any of the files within the `@salesforce/retail-react-app` package, the file in the overrides directory is loaded instead of the file in the package. Only the base of the filename needs to be the same for the override to happen. The file extensions can be different.

As you build your app, you can gradually add files from the base template to your overrides directory.

**warning:** The more files that you override, the more effort is required to keep up with changes in the base template.

To see template extensibility in action, generate a fresh PWA Kit v3 project by running `npx @salesforce/pwa-kit-create-app@latest --outputDir <path/to/new/local/project>`.

The generated project uses Retail React App base template, which gives you an app that looks mostly the same as the one found at https://pwa-kit.mobify-storefront.com/.

## Tutorials

In the template extensibility tutorials you’ll learn how to add some common customizations to your site:

- [Customize a Component](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/create-a-custom-component.md) — component-level extensibility
- [Customize a Page](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/customize-a-page.md) — page-level extensibility

## Configuration

**note:** The instructions in this section assume that you want to enable template extensibility for an existing project that wasn't generated with the feature already enabled.

### Upgrade Your Retail React App Version

To upgrade to the latest version of the Retail React App, run this command:

`npm install @salesforce/retail-react-app@latest`

After running that command, we recommend that you test your site to confirm that it works as expected.

### Define a Base Template

To define a base template, add `@salesforce/retail-react-app` (or a different template) as an npm dependency in your project's `package.json` file.

Then add a `ccExtensibility` key to `package.json` with the following keys and values:

```json
  "ccExtensibility": {
    "extends": "@salesforce/retail-react-app",
    "overridesDir": "overrides"
  }
```

If you’re using a base template other than the Retail React App, don't forget to replace `@salesforce/retail-react-app` with the other template's package identifier.

You can replace the values for `overridesDir` with a custom directory name, but we recommend using `overrides` for the sake of consistency among projects (and our example code).

**warning:** Don’t list the same npm dependencies in both the main project and the base template. Confirm that the dependencies listed in your project's `package.json` are different from those in the base template. This ensures that `@salesforce/pwa-kit-dev` can differentiate between the two in dependency resolution. Define a base template in the main project’s `package.json` as described under [Configuration](#configuration). The main project can’t inherit from itself.

### Version Conflicts

Your project must not have version clashes with the base template's npm dependencies listed in its `package.json` file. If the underlying template uses `@chakra-ui`, your project must also have it as a dependency, and it must be the same version. This precaution prevents accidental bloat in your bundle (not to mention functional breakage) due to conflicting versions of the same package. There is one exception to this rule: When you have added overrides for all of the files in the base template that imports a given dependency. In that case, the base template’s version of the dependency is never imported in your project because you have eliminated all files that import it via overrides.

Adding additional npm dependencies that are not used in the underlying template is just fine. 👌

## Required Project Files

Every PWA Kit project deployed to Managed Runtime must have the following files:

- `<overridesDir>/app/main.jsx`
- `<overridesDir>/app/ssr.js`
- `<overridesDir>/app/routes.jsx`
- `<overridesDir>/app/request-processor.js`
- `config/default.js` (exception: if you are using the `mobify` key in `package.json` to store your site config data)

To customize behaviors in the project, it is common to override these files in `@salesforce/retail-react-app`:

- `app/pages/home/index.jsx`: Removing the default Salesforce marketing content from the home page is a first step almost all projects.
- `app/static/*`: These files are defaults that serve icons used by desktop and mobile browsers to brand your site. Update them to match your brand.
- `app/constants.js`
- `app/assets/svg/brand-logo.svg`: This file is overridden in the generator project. Follow this example to override other icons in your project.

## Imports and Exports

The intent of this "filesystem as an API" setup is to help you find the underlying files, copy them, then customize the behavior and logic. Breaking down code into smaller files that orchestrate many subcomponents makes it easier to target only the behavior that you intend to override.

That being said, you sometimes have to copy a file into your overrides to change only a portion of the behavior of that file. Whenever possible, it's best to import the underlying template exports and re-export them so that changes to the template version don't require manual code updates in your extended project.

For example, in the `routes.jsx` file [in a generated project](https://github.com/SalesforceCommerceCloud/pwa-kit/blob/release-3.0.x/packages/pwa-kit-create-app/assets/bootstrap/js/overrides/app/routes.jsx.hbs), notice that the default routes are imported via `import {routes as _routes} from '@salesforce/retail-react-app/app/routes'` with `_routes` intended as a convention to indicate that these default routes are managed by an external dependency. Just like the file `@salesforce/retail-react-app/app/routes.jsx`, our custom implementation of `routes.jsx` exports routes; it adds a `/` (Home) route. The new route takes precedence over the default route because React Router finds the first item of a given pathname in the routes array.

### Relative Imports

Relative imports are the best approach for most projects that use template extensibility. The import behavior for the files in your base template (for example, `@salesforce/retail-react-app`) has special logic that gives precedence to the file in your overrides directory. This import logic **does not apply** to the files in your overrides directory. Therefore, we recommend using relative imports for most implementations.

### Avoid Importing Conflicting Files

Template extensibility can be complex to think about in terms of the "mental model", but an unexpected "gotcha" that can come up is accidentally importing two different conflicting files. A PWA Kit project is built via `@salesforce/pwa-kit-dev`, which uses [webpack](https://webpack.js.org/) internally. There is a plug-in in `@salesforce/pwa-kit-dev` that enables the "override" functionality of template extensibility. This plug-in inspects all webpack file requests and asks two questions:

1. Does this file request originate in the base template?
2. Does this file exist in the overrides directory?

If the answer to both questions is "yes", the file request is rewritten at build time to point to the file in the overrides directory.

This logic does not come into play for webpack file requests that originate in the overrides directory. As such, it is possible to import **the same file** from both the overrides directory and the base template. If this situation happens with, for example, `@saleforce/retail-react-app/my-file` and `<overrides directory>/my-file` being imported in the same bundle, webpack throws a confusing error along the lines of `can’t find <export name> from <filename>`. Webpack throws this error because the bundle doesn’t know which import is the intended target for bundle inclusion.

It’s important to avoid importing files from the base template when an equivalent file exists in overrides, with **one notable exception**. As covered earlier in the code example in the [Special Files](#special-files) section and demonstrated with `constants.js`, it's better to import the underlying template and re-export all of its exports, overriding or appending as few exports as are needed.

## Global Components

When you need to override the `app/components/_app/index.jsx` component, there are many global components, such as `Header`, `Footer`, and `DrawerMenu`. After the `_app/index.jsx` override is in place, any attempts by the base template to import this component will reroute the file request to `<ccExtensibility.overridesDir>/app/components/_app/index.jsx`. But there’s a catch! Because `Header` and `Footer` are imported by `app/components/_app/index.jsx`, the import must be updated in `_app/index.jsx` too! Otherwise, `_app/index.jsx` imports `Header` and `Footer` from the base template.

**important:** ECMAScript imports originating in `ccExtensibility.extends` are "magical" in that `@salesforce/pwa-kit-dev` checks in multiple places for a file of that name, with `ccExtensibility.overridesDir` taking precedence.

On the other hand, imports originating in `<ccExtensibility.overridesDir>/*` do not have magical behavior, thus you must target the files you mean to, and so `<ccExtensibility.overridesDir>/app/components/header/index.jsx` must be imported explicitly in `<ccExtensibility.overridesDir>/app/components/_app/index.jsx` like this:

```javascript
// <ccExtensibility.overridesDir>/app/components/_app/index.jsx

import Header from "../header";
```

Do not import from the package like this because it bypasses the header in your overrides directory:

```javascript
// <ccExtensibility.overridesDir>/app/components/_app/index.jsx

import Header from "@salesforce/retail-react-app/components/header";
```

## Special Files

Take note that `routes.jsx` is a special file. It forms the "entryPoint," in webpack terminology, for the entire application. If you have anything set up incorrectly in `routes.jsx`, it causes your whole app to fail in the compile phase as the route-based chunking in `pwa-kit-dev` does not resolve properly. For this reason, we include an example of how to properly extend routes properly by mixing imports from the default `@salesforce/retail-react-app/app/routes.jsx` and a local `routes.jsx` in the `overridesDir`.

Because the imports here are at "the top of the tree", if you override these files and then override `footer.jsx`, you must come back to `_app/index.jsx` and modify that import to point to your relative template import.

## Maintain Consistent Exports

A known limitation of the template extensibility system is that, by virtue of magically pulling in, for example `retail-react-app/constants`, anytime the base template (`@salesforce/retail-react-app`) imports this file, it expects the same values to be exported.

**warning:** A file in overrides that fails to export the same ECMAScript exports as its equivalent in the base template can cause unexpected errors like the one below.

Adding a `constants.js` file to your overrides directory like this causes an error:

```javascript
// constants.js
export const CUSTOM_MESSAGE = "CUSTOM MESSAGE";
```

Example error message:

```
WARNING in ../template-retail-react-app/app/components/_app/index.jsx 74:10-40
  export 'CAT_MENU_DEFAULT_ROOT_CATEGORY' (imported as 'CAT_MENU_DEFAULT_ROOT_CATEGORY') was not found in 'retail-react-app/app/constants' (possible exports: CUSTOM_MESSAGE)
@ ../pwa-kit-react-sdk/dist/ssr/browser/main.js 13:34-73
@ ./overrides/app/main.jsx 9:0-82 12:22-27 12:31-52
```

The reason for this error is that `CAT_MENU_DEFAULT_ROOT_CATEGORY` is an expected export in `@salesforce/retail-react-app/components/_app/index.jsx` and in the process of overriding it with the sole export `CUSTOM_MESSAGE` above, your override breaks the underlying "API contract" (the ability of files to depend upon a given value, in this case `CAT_MENU_DEFAULT_ROOT_CATEGORY`) being exported by `constants.js`

The correct approach would be as follows. This approach avoids the omission of `CAT_MENU_DEFAULT_ROOT_CATEGORY` as a required and expected export. Thus we maintain the consistency of the exported API.

This approach only works for additive changes. In the following example, we add a `CUSTOM_MESSAGE` export that is not in the underlying `retail-react-app/constants.js` file’s exports.

```javascript
// constants.js
export * from "retail-react-app/constants";
export const CUSTOM_MESSAGE = "CUSTOM MESSAGE";
```

This approach works for the following scenario, where `DEFAULT_LOCALE` is exported by `retail-react-app/constants`, and we are mutating that value:

```javascript
// constants.js
import {
  DEFAULT_LIMIT_VALUES,
  DEFAULT_SEARCH_PARAMS,
} from "@salesforce/retail-react-app/app/constants";

// original value is 25
DEFAULT_LIMIT_VALUES[0] = 3;
DEFAULT_SEARCH_PARAMS.limit = 3;

export { DEFAULT_LIMIT_VALUES, DEFAULT_SEARCH_PARAMS };

export * from "@salesforce/retail-react-app/app/constants";
```

## Template Hooks

Template hooks are a new way to interact with the Retail React App template that has historically been available via the command `npx pwa-kit-create-app` (now renamed to `npx @salesforce/pwa-kit-create-app`).

As part of the template extensibility feature, new "template hooks" have been added to `@salesforce/retail-react-app` that support global addition of a small subset of components, enumerated in the following list. By default, each of these components return `null` and is intentionally empty in order to avoid adding unneeded bloat to a completed PWA Kit implementation project. The base `@salesforce/retail-react-app` never adds any functionality to these components. Template hooks always return `null` in order to ensure that customer implementations can "hook" into the template in these places to customize the project without having to override more files than necessary.

As of `@salesforce/retail-react-app@1.0.0` the following template hooks are available:

- `app/components/_app/partials/above-header.jsx`
- `app/pages/product-list/partials/above-page-header.jsx`

## Create a Base Template

At the time of PWA Kit v3's release, there is only one extensible base template that is publicly available: `@salesforce/retail-react-app` (more are expected later).

To be used as a base template, a PWA Kit project must be published to npm and all of its ECMAScript imports must be prefixed with a value that matches the package name. For example, `@salesforce/retail-react-app` is published on npm, and its imports are prefixed with `@salesforce/retail-react-app`. This prefix is a reference to the package's root directory, which is necessary for it to work properly as a base template.

To use a PWA Kit project as an extensible base template, it must use `<npm package name>` for all of its imports. For example, `@salesforce/retail-react-app` adds `ccExtensibility` in `package.json`, which ensures that local IDE references (for example, `@salesforce/retail-react-app/app/components/_app`) resolve properly.

## Template Extensibility Best Practices

- Use template extensibility instead of copying the [Retail React App](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/retail-react-app.html) template and editing it.
- As you make changes, test your project regularly to identify and fix any issues that come up.
- Test the customized functionality in a non-production environment before deploying it to production.
- Iterate on your overrides as needed to refine the behavior.

## Troubleshoot Template Extensibility

This section provides suggested solutions for common errors that you might encounter while using template extensibility.

### Customizations Don’t Appear on Your Site

After you changed files in your project the updates don’t appear when you preview your site.

**Cause:** You didn’t restart your local server.

**Suggested Solution:** Run `npm start` then preview your site again.

### Configuration Incomplete

This applies only if you’re using a version of PWA Kit older than version 3.

**Cause:** Your `package.json` file is missing the required `ccExtensibility `configuration.

**Suggested Solution:** Complete this [Configuration](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/template-extensibility.html#configuration) in `package.json`.

### Required Project Files Missing

**Cause:** Required files are missing from the the overrides directory (`overridesDir`).

**Suggested Solution:** Ensure that your project includes all the required files in the `overrides `directory. See [Required Project Files](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/template-extensibility.html#required-project-files).

### Version Conflicts

**Cause:** There are conflicting versions of dependencies between the base template and your project

**Suggested Solution:** Ensure both the base template and your project use the same version of shared dependencies. See [Version Conflicts](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/template-extensibility.html#version-conflicts).

## See Also

- [Retail React App](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/retail-react-app.html)
- [Debug PWA Kit Apps](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/debugging.html)
- [Customization with Hooks](https://developer.salesforce.com/docs/commerce/commerce-api/guide/extensibility_via_hooks.html)
- [Custom APIs](https://developer.salesforce.com/docs/commerce/commerce-api/guide/custom-apis.html)
