---
schema_version: "1"
id: 1f6caee203e282d585f016539447f0c8671b983d4a3a7faac657ad054443997f
title: Launch Your Storefront
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/pwa-kit-managed-runtime/guides/launching-your-storefront.md
canonical_url: https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/launching-your-storefront.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 02e50dbc73c9c5fedc98047ab00a018526fd7751494caafd75f77914e906868b
products:
  - Composable Storefront
  - Salesforce APIs
---
# Launch Your Storefront

This guide describes how to launch a Progressive Web App (PWA) Kit storefront and make it accessible from its official, public web address.

Throughout this guide we use an example storefront with the following attributes:

- Production URL: `https://www.example.com`
- Project ID: `example`
- Environment IDs: `staging` and `production`

Before running the commands, replace any placeholders with actual values. Placeholders are formatted like this: `$PLACEHOLDER`.

## When to Use a Third-Party CDN

See [Decide which CDN to Use](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/decide-on-cdn.md).

## Before You Begin

This guide assumes that you have access to the [Runtime Admin](https://runtime.commercecloud.com/) web application and the [Managed Runtime API](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=Summary) to perform administrative tasks. To get access to these tools, contact your B2C Commerce administrator and ask them to add either one of the following roles to your account using Account Manager: **Managed Runtime User** or **Managed Runtime Admin**.

To make requests to the [Managed Runtime API](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=Summary), you must include an API key in the HTTP request `Authorization` header with the value, `Bearer $API_KEY`. For all the sample requests provided, don’t forget to replace `$API_KEY` with your actual API key.

To find your API key, log in to [Runtime Admin](https://runtime.commercecloud.com/) and go to the [Account Settings](https://runtime.commercecloud.com/account/settings) page.

**Important**: Treat your API key like a password because it allows scripts to complete operations on your behalf.

You need access to your DNS provider to create and update CNAME records, as well as access to your third-party CDN provider (as applicable).

### What Is Mobify?

In this guide, the word “Mobify” appears in a few places. Mobify is the name of the company that originally developed the technology that became PWA Kit and Managed Runtime. In 2020, Salesforce acquired Mobify along with all of its technology.

The Mobify brand name appears in the `mobify-storefront.com` domain used to host your storefront and the `cloud.mobify.com` domain used by the Managed Runtime API.

### Use a Custom Domain for Local Development

If you need to add conditional logic that alters the behavior of your site depending on the domain used, it’s easier to test this logic when your local development server can use a custom domain. Why would you need to add this kind of logic? Consider, for example, the need to look up a different SLAS Client ID depending on the domain.

To run your local development server using a custom domain:

1. Modify your local computer's DNS to resolve your custom domain to `127.0.0.1` (localhost).
2. Edit `ssr.js`.
3. In the `options` passed to `runtime.createHandler`, set the port to `80`.
4. Run `EXTERNAL_DOMAIN_NAME=www.example.com npm start`, replacing the value of `example.com` with your custom domain. _Running the server on port `80` can sometimes require administrative privileges._

Requests from your browser to the custom domain are now resolved and routed to your local development server!

## Launching an Environment

The process for launching an environment is the same for staging and production, with the only difference being the domain name and the Managed Runtime environment used.

**warning:** We strongly recommend going through the launch process on a staging environment first before repeating the process on production. These steps should be completed as soon as you start a PWA Kit project and at least two weeks before your launch date.

For the instructions provided, imagine you’re launching a storefront at `staging.example.com`, your project ID in Managed Runtime is `example`, and your bundle is deployed to an environment called `staging`.

## 1. Create Your Environment

Use [Runtime Admin](https://runtime.commercecloud.com/) or [Managed Runtime API](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/managed-runtime-api?meta=Summary) to create an environment called `staging` to practice launching the storefront.

Use the [B2C CLI](https://developer.salesforce.com/docs/commerce/b2c-commerce/guides/b2c-developer-tooling.md):

```bash
export MRT_API_KEY="$API_KEY"

npx @salesforce/b2c-cli mrt env create staging --project my-storefront
```

Alternatively, use the API. Here's a sample request that uses the [projects_target_create](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_create) endpoint to create an environment. Replace `example` in the request with your actual project ID string and `$API_KEY` with your API key:

```bash
curl 'https://cloud.mobify.com/api/projects/example/target/' \
  --request 'POST' \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{ "name" : "staging" }'
```

For instructions on creating an environment with [Runtime Admin](https://runtime.commercecloud.com/), see our guide to [Managed Runtime Administration](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.md#create-an-environment).

## 2. Ensure APIs Are Accessible

Many PWA Kit implementations make requests to OCAPI or controllers in addition to B2C Commerce API.

You must ensure your B2C Commerce instance is reachable by Managed Runtime.

Making the APIs reachable typically involves configuring eCDN to make your B2C Commerce instance available at an alternative domain like `ecom.example.com`. For more information, refer to the [eCDN setup and configuration documentation](https://documentation.b2c.commercecloud.salesforce.com/DOC2/topic/com.demandware.dochelp/content/b2c_commerce/topics/admin/b2c_configure_the_embedded_cdn.html).

After your domain is configured, update your environment’s proxy settings to use it. For more information, see our guide to [Proxying Requests](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/proxying-requests.md).

## 3. TLS Certificates

**important:** This step is not required when using a third-party CDN or eCDN. Consult your CDN vendor documentation for configuring certs.

If you are routing traffic directly to the Managed Runtime CDN, then Managed Runtime issues and manages TLS certificates on your behalf.

### Certificate Management

Organization Admins and Organization Users with the Managed Certificates permission can now manage TLS certificates directly through Runtime Admin. This provides enhanced control over certificate lifecycle management without requiring support tickets for routine certificate operations.

**Prerequisites for Certificate Management:**

- Organization Admin role OR Organization User with Managed Certificates permission assigned.
- Access to [Runtime Admin](https://runtime.commercecloud.com/).

### Request a TLS Certificate

If you have the appropriate permissions, you can request certificates directly through Runtime Admin. See [Organization Certificate Management](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.md#certificate-management)

### Domain Validation Requirements

Make sure that these requirements are met.

- The domain's [`CAA` records](https://letsencrypt.org/docs/caa/) are set to allow [AWS to issue certs](https://docs.aws.amazon.com/acm/latest/userguide/setup-caa.html) by including these values:

```
0 issue "amazon.com"
0 issuewild "amazon.com"
```

- You can create CNAME records for domain validation within **72 hours** of receiving validation details.

### TLS Certificate Renewal Process

Managed Runtime automatically renews TLS certificates as long as:

- The CNAME record remains in place to validate ownership.
- The TLS certificate is in use by at least one environment.
- The domain's [`CAA` records](https://letsencrypt.org/docs/caa/) are set to allow [AWS to issue certs](https://docs.aws.amazon.com/acm/latest/userguide/setup-caa.html) by including these values:

```
0 issue "amazon.com"
0 issuewild "amazon.com"
```

## 4. DNS CNAME

**important:** This step isn't required when using a third-party CDN or eCDN.

Reduce the time to live (TTL) for `staging.example.com` to one minute. _Reducing the TTL speeds up the DNS cutover process, and if something goes wrong, allows you to roll back quickly._

You can verify the TTL using the [`dig`](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/%3Chttps://en.wikipedia.org/wiki/Dig_(command)>) command:

```sh
dig +nocmd +noall +answer 'staging.example.com'
```

## 5. Configure Your Environment

### Option 1: Use a Third-Party CDN or eCDN

Set an environment’s access control header using Runtime Admin's [Access Control Settings](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managed-runtime-administration.md#access-control-headers) or the [access_control_header](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_access_control_header_create) API.

In this example, we use the API to set an access control header with the header value `25pn5dec7f1c`:

```bash
curl "https://cloud.mobify.com/api/projects/$PROJECT/target/$TARGET/access-control-header/" \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{ "value" : "25pn5dec7f1c" }'
```

The access control header value will be used during [Perform the Cutover](#6-perform-the-cutover) to prevent direct access to the environment.

### Option 2: Use the Managed Runtime CDN

Configure the environment to receive traffic from the host `staging.example.com`.

**important:** A hostname can be set as the External Hostname for only one environment at a time. If the hostname is already configured on another environment, this step fails until it's removed from that environment.

- Navigate to the Environment Settings page.
- Under Advanced, click **Edit**.
- Select the desired certificate (`staging.example.com` or `*.example.com`).
- Provide a subdomain if using a wildcard certificate.
- Click **Save**.

Use the [B2C CLI](https://developer.salesforce.com/docs/commerce/b2c-commerce/guides/b2c-developer-tooling.md):

```bash
npx @salesforce/b2c-cli mrt env update \
  --project my-storefront --environment staging \
  --external-domain example.com --external-hostname staging.example.com
```

Optionally, you can configure the environment via the API. Update the environment’s `ssr_external_domain` and `ssr_external_hostname` settings using the [projects_target_partial_update](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=projects_target_partial_update) API.

```bash
curl 'https://cloud.mobify.com/api/projects/example/target/staging/' \
  --request 'PATCH' \
  --header "Authorization: Bearer $API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "ssr_external_domain": "example.com",
    "ssr_external_hostname": "staging.example.com"
}'
```

**important:** After this step, the environment is no longer accessible at its `mobify-storefront.com` or `exp-delivery.com` default domain.

Verify that the new settings are in effect using a [cURL](https://daniel.haxx.se/blog/2018/04/05/curl-another-host/) command that makes a request with [DNS spoofing](https://daniel.haxx.se/blog/2018/04/05/curl-another-host/):

```bash
curl 'https://staging.example.com' \
    --resolve 'staging.example.com:443:'"$(dig +short 'example-staging-cdn.sfdc-8tgtt5-ecom1.exp-delivery.com' | tail -n1)"
```

## 6. Perform the Cutover

The cutover process is different depending on whether you use a third-party CDN, eCDN, or the Managed Runtime CDN.

### Option 1: Use a Third-Party CDN

Configure your Managed Runtime environment as an origin in your CDN:

- set the `Host` header to match your environment `{{project}}-{{environment}}.sfdc-8tgtt5-ecom1.exp-delivery.com`
- forward the request method
- forward the path (including query string)
- forward the headers
- forward the body
- forward all traffic over HTTPS
- obey HTTP caching headers
- set the `x-sfdc-access-control` header value if configured for your environment

Refer to your CDN provider documentation for detailed guidance.

**note:** Managed Runtime routes requests to environments using the HTTP `Host` header. Requests with an incorrect host are rejected with an HTTP 403 Bad Request response.

Consider adding a handler to reflect HTTP requests and verify that your CDN is configured correctly:

```js
// ssr.js
app.all('/echo', function echoHandler({method, path, headers, body}, res) {
  res.send({method, path, headers, body})
})
```

Also consider adding a [proxy](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/proxying-requests.html#configure-managed-runtime-environments) with [httpbin.org/anything](https://httpbin.org/anything) to verify headers passed to proxies are sent correctly.

If you encounter issues, use the techniques described in [Debug PWA Kit Apps](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/debugging.html).

### Option 2: Use eCDN

Update your eCDN routing rules to route traffic to your Managed Runtime environment. Review the [eCDN MRT Rules](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/ecdn-rules-for-phased-headless-rollout.html#route-traffic-to-managed-runtime) guide for more information. You can also [Configure MRT Routing Rules in Business Manager](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/configure-mrt-routing-bm.md).

Use the [B2C CLI](https://developer.salesforce.com/docs/commerce/b2c-commerce/guides/b2c-developer-tooling.md) to send the header configured in [step 5](#option-1-use-a-third-party-cdn-or-ecdn):

```bash
# Required scopes: sfcc.cdn-zones, sfcc.cdn-zones.rw
export SFCC_CLIENT_ID='your-account-manager-client-id'
export SFCC_CLIENT_SECRET='your-account-manager-client-secret'
export SFCC_SHORTCODE='your-short-code'

npx @salesforce/b2c-cli ecdn zones list --tenant-id abcd_stg

npx @salesforce/b2c-cli ecdn origin-headers set \
  --tenant-id abcd_stg --zone stg-abcd-example-com.cc-ecdn.net \
  --header-value 'example-header-value'
```

Alternatively, call [upsertOriginHeaderModification](https://developer.salesforce.com/docs/commerce/commerce-api/references/zones?meta=upsertOriginHeaderModification):

```bash
curl  "https://$CODE.api.commercecloud.salesforce.com/cdn/zones/v1/organizations/$ORG/zones/$ZONE/origin-header-modification/mrt" \
  --request 'PUT' \
  --header "Authorization: Bearer $TOKEN" \
  --header 'Content-Type: application/json' \
  --data '{ "headerValue" : "25pn5dec7f1c" }'
```

### Option 3: Use the Managed Runtime CDN

Perform a DNS cutover to point your domain from the old origin to the Managed Runtime CDN.

#### Find Your DNS Configuration Values

To find the correct DNS values for your environment, check the DNS configuration in Environment Settings.

1. In your environment's overview page in [Runtime Admin](https://runtime.commercecloud.com/), click **Environment Settings**.
2. View the **DNS Configuration** section for the exact CNAME record values.

#### Manual DNS Configuration

Alternatively, the Managed Runtime CDN stable domain follows the convention of one of these default domains:

- `{{project}}-{{environment}}-cdn.sfdc-8tgtt5-ecom1.exp-delivery.com`
- `{{project}}-{{environment}}-cdn.mobify-storefront.com`

Where `{{project}}` is your project ID, and `{{environment}}` is your environment ID.

#### Update Your DNS Records

1. Update the DNS CNAME record for `staging.example.com` to the value shown in your DNS configuration (e.g., `example-staging-cdn.sfdc-8tgtt5-ecom1.exp-delivery.com`).
2. Open your web browser and navigate to `staging.example.com`.

Congrats, you’ve completed your launch! 🥳

After completing these instructions for a staging site, you can repeat the same process with the production domain and production environment.

## 7. Site Monitoring

From here, the Customer Success Group assists you in monitoring the site’s traffic to make sure that the launch has succeeded. The goal is to ensure that everything happens as expected during launch!

After launch, customers with a Signature Success Plan receive proactive site monitoring. To take advantage of this increased monitoring service, you must mark your environment as `production`. For more information, see the section on [environments](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/mrt-overview.html#environments) in the Managed Runtime Overview.

## Technical Limitations

- The `ssr_external_hostname` target setting controls which host the environment receives traffic from. If the HTTP `Host` header of a request doesn’t match this value, the request fails with a 403 error.
- A given hostname can only be set as the `ssr_external_hostname` for one environment at a time. Attempting to set a hostname that's already in use by another environment fails.
- Currently, Salesforce doesn’t support storefront URLs with a bare domain like [`example.com`](http://example.com/) (with no `www` subdomain). To use a bare domain, you must set up a server to redirect requests from the bare domain to your CNAME.

## See Also

- [Pre-Build and Go-Live Best Practices Checklist](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/pwa-best-practices.md)
- [Monitor Your PWA Kit Site](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/monitor-site.md)
