Skip to content

Commit 17af4bf

Browse files
committed
sfnext guide
1 parent da3b062 commit 17af4bf

5 files changed

Lines changed: 219 additions & 0 deletions

File tree

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const guideSidebar = [
5151
{ text: 'Scaffolding', link: '/guide/scaffolding' },
5252
{ text: 'IDE Support', link: '/guide/ide-support' },
5353
{ text: 'Security', link: '/guide/security' },
54+
{ text: 'Storefront Next', link: '/guide/storefront-next' },
5455
],
5556
},
5657
{

docs/cli/mrt.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ b2c mrt env create prod -p my-storefront --name "Production" \
286286
| `--external-domain` | External domain for SSR |
287287
| `--allow-cookies` | Forward HTTP cookies |
288288
| `--enable-source-maps` | Enable source maps |
289+
| `--proxy` | Proxy configuration in format `path=host` (repeatable) |
290+
| `--wait`, `-w` | Wait for the environment to be ready before returning |
289291

290292
### b2c mrt env get
291293

docs/guide/storefront-next.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
description: Set up Storefront Next development environments using the B2C CLI to create sandboxes, SLAS clients, MRT environments, and deploy.
3+
---
4+
5+
# Storefront Next
6+
7+
::: warning Pilot Preview
8+
Storefront Next is currently in pilot. Access to Storefront Next is limited to pilot customers. Features and configuration may change.
9+
:::
10+
11+
This guide walks through setting up the infrastructure for a Storefront Next project using the B2C CLI. The steps cover creating a sandbox, configuring SLAS authentication, setting up an MRT environment, configuring environment variables, and deploying. Not all steps are required — skip any that are already complete for your project.
12+
13+
## Prerequisites
14+
15+
- [B2C CLI installed](/guide/installation) or use `npx @salesforce/b2c-cli` to run commands without installing
16+
- Commerce Cloud realm access
17+
- A Storefront Next project
18+
- Appropriate Account Manager roles (detailed per step below)
19+
20+
## Step 1: Create an On-Demand Sandbox (Optional)
21+
22+
If you need a new sandbox instance for development, create one with the CLI.
23+
24+
**Required Role:** Sandbox API User (see [Authentication Setup](/guide/authentication))
25+
26+
```bash
27+
b2c sandbox create --realm <REALM> --wait
28+
```
29+
30+
Note the hostname from the output — you'll need it for later configuration.
31+
32+
After creating a sandbox, you'll need to create or import sites. You can import SFRA in Business Manager under **Administration > Site Development > Site Import & Export**.
33+
34+
See [Sandbox Commands](/cli/sandbox) for more options.
35+
36+
## Step 2: Create a SLAS Client
37+
38+
Create a SLAS client for your storefront to handle shopper authentication.
39+
40+
**Required Role:** SLAS Organization Administrator with a tenant filter matching your tenant.
41+
42+
Your tenant ID is found in Business Manager under **Administration > Site Development > Salesforce Commerce API Settings**. It is the organization ID without the `f_ecom_` prefix — for example, if your organization ID is `f_ecom_abcd_001`, your tenant ID is `abcd_001`. You can pass either form to the `--tenant-id` flag and the CLI will handle it.
43+
44+
```bash
45+
b2c slas client create \
46+
--tenant-id <TENANT_ID> \
47+
--channels <SITE_ID> \
48+
--redirect-uri "http://localhost:5173,https://*.exp-delivery.com/callback" \
49+
--default-scopes
50+
```
51+
52+
The client is created as a private client by default (no `--public` flag needed).
53+
54+
::: warning
55+
Save the client ID and secret from the output — the secret is only shown once and cannot be retrieved later.
56+
:::
57+
58+
See [SLAS Commands](/cli/slas) for more options.
59+
60+
## Step 3: Create an MRT Environment
61+
62+
Set up a Managed Runtime environment to host your storefront.
63+
64+
**Prerequisites:**
65+
- An MRT API key from [runtime.commercecloud.com](https://runtime.commercecloud.com/)
66+
- An MRT project (see [`b2c mrt project create`](/cli/mrt#b2c-mrt-project-create) to create one)
67+
68+
::: tip
69+
Configure your API key in `~/.mobify` or via the `SFCC_MRT_API_KEY` environment variable so you don't need to pass it on every command. See [Configuration](/guide/configuration) for details.
70+
:::
71+
72+
Find your short code in Business Manager under **Administration > Salesforce Commerce API Settings**.
73+
74+
```bash
75+
b2c mrt env create <SLUG> \
76+
--project <PROJECT> \
77+
--name "<NAME>" \
78+
--allow-cookies \
79+
--proxy "api=<SHORT_CODE>.api.commercecloud.salesforce.com" \
80+
--wait
81+
```
82+
83+
### Connect the B2C Commerce Instance
84+
85+
After creating the environment, link it to your B2C Commerce instance by setting the tenant and site IDs:
86+
87+
```bash
88+
b2c mrt env b2c -p <PROJECT> -e <ENVIRONMENT> \
89+
--instance-id <TENANT_ID> \
90+
--sites <SITE_ID>
91+
```
92+
93+
See [MRT Commands](/cli/mrt) for more options.
94+
95+
## Step 4: Set Environment Variables
96+
97+
Configure your MRT environment with the required Storefront Next variables.
98+
99+
Your organization ID and short code are found in Business Manager under **Administration > Site Development > Salesforce Commerce API Settings**. The organization ID has the form `f_ecom_abcd_001`.
100+
101+
```bash
102+
b2c mrt env var set \
103+
PUBLIC__app__commerce__api__clientId=<SLAS_CLIENT_ID> \
104+
PUBLIC__app__commerce__api__organizationId=<ORG_ID> \
105+
PUBLIC__app__commerce__api__siteId=<SITE_ID> \
106+
PUBLIC__app__commerce__api__shortCode=<SHORT_CODE> \
107+
PUBLIC__app__commerce__api__proxy=/mobify/proxy/api \
108+
PUBLIC__app__commerce__api__callback=/callback \
109+
PUBLIC__app__commerce__api__privateKeyEnabled=true \
110+
COMMERCE_API_SLAS_SECRET=<SLAS_CLIENT_SECRET> \
111+
PUBLIC__app__defaultSiteId=<SITE_ID> \
112+
-p <PROJECT> -e <ENVIRONMENT>
113+
```
114+
115+
### Variable Reference
116+
117+
| Variable | Description |
118+
|----------|-------------|
119+
| `PUBLIC__app__commerce__api__clientId` | SLAS client ID from Step 2 |
120+
| `PUBLIC__app__commerce__api__organizationId` | Commerce Cloud organization ID (e.g., `f_ecom_aaaa_prd`) |
121+
| `PUBLIC__app__commerce__api__siteId` | Site ID (e.g., `RefArch`) |
122+
| `PUBLIC__app__commerce__api__shortCode` | Short code from Business Manager |
123+
| `PUBLIC__app__commerce__api__proxy` | Proxy path for API requests |
124+
| `PUBLIC__app__commerce__api__callback` | OAuth callback path |
125+
| `PUBLIC__app__commerce__api__privateKeyEnabled` | Must be `true` for private SLAS clients |
126+
| `COMMERCE_API_SLAS_SECRET` | SLAS client secret from Step 2 |
127+
| `PUBLIC__app__defaultSiteId` | Default site ID for the storefront |
128+
129+
Most of these values match what's in your project's `.env` file. The `privateKeyEnabled` variable must be set to `true` when using a private SLAS client.
130+
131+
::: warning
132+
The `COMMERCE_API_SLAS_SECRET` contains sensitive credentials. Treat it accordingly and avoid committing it to source control.
133+
:::
134+
135+
::: tip
136+
If your project uses multiple sites, you can also set `PUBLIC__app__commerce__sites` with your sites configuration.
137+
:::
138+
139+
## Step 5: Deploy
140+
141+
Deploy your Storefront Next project from the project directory.
142+
143+
**Primary method** using the Storefront Next CLI:
144+
145+
```bash
146+
pnpm sfnext push --project-slug <PROJECT> --target <ENVIRONMENT>
147+
```
148+
149+
This is run from your Storefront Next project directory.
150+
151+
**Alternative** using the B2C CLI directly (builds and deploys):
152+
153+
```bash
154+
b2c mrt bundle deploy -p <PROJECT> -e <ENVIRONMENT> \
155+
--ssr-only "server/**/*,loader.js,sfnext-server-*.mjs,streamingHandler.{js,mjs,cjs},streamingHandler.{js,mjs,cjs}.map,!static/**/*" \
156+
--ssr-shared "client/**/*,static/**/*,**/*.css,**/*.png,**/*.jpg,**/*.jpeg,**/*.gif,**/*.svg,**/*.ico,**/*.woff,**/*.woff2,**/*.ttf,**/*.eot"
157+
```
158+
159+
The `--ssr-only` and `--ssr-shared` patterns are required for the Storefront Next bundle structure.
160+
161+
## Summary
162+
163+
| Step | Command | Required? |
164+
|------|---------|-----------|
165+
| 1. Create Sandbox | `b2c sandbox create` | Optional |
166+
| 2. Create SLAS Client | `b2c slas client create` | Yes |
167+
| 3. Create MRT Environment | `b2c mrt env create` | Yes |
168+
| 4. Set Environment Variables | `b2c mrt env var set` | Yes |
169+
| 5. Deploy | `pnpm sfnext push` or `b2c mrt bundle deploy` | Yes |
170+
171+
## Next Steps
172+
173+
- [Configuration](/guide/configuration) — configure CLI defaults and credentials
174+
- [Authentication Setup](/guide/authentication) — detailed auth setup for all commands
175+
- [Sandbox Commands](/cli/sandbox) — manage on-demand sandboxes
176+
- [SLAS Commands](/cli/slas) — manage SLAS clients and tenants
177+
- [MRT Commands](/cli/mrt) — manage MRT projects, environments, and deployments

packages/b2c-tooling-sdk/src/cli/oauth-command.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ export abstract class OAuthCommand<T extends typeof Command> extends BaseCommand
218218
),
219219
);
220220
}
221+
// Strip optional f_ecom_ prefix so users can pass either the organization ID or tenant ID
222+
if (tenantId.startsWith('f_ecom_')) {
223+
return tenantId.slice('f_ecom_'.length);
224+
}
221225
return tenantId;
222226
}
223227
}

packages/b2c-tooling-sdk/test/cli/oauth-command.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ class TestOAuthCommand extends OAuthCommand<typeof TestOAuthCommand> {
3333
public testGetOAuthStrategy() {
3434
return this.getOAuthStrategy();
3535
}
36+
37+
public testRequireTenantId() {
38+
return this.requireTenantId();
39+
}
3640
}
3741

3842
// Test command with default client ID (simulates AmCommand/OdsCommand behavior)
@@ -100,6 +104,37 @@ describe('cli/oauth-command', () => {
100104
});
101105
});
102106

107+
describe('requireTenantId', () => {
108+
it('returns tenant ID as-is when no f_ecom_ prefix', async () => {
109+
stubParse(command, {'client-id': 'test-client', 'tenant-id': 'abcd_001'});
110+
await command.init();
111+
112+
expect(command.testRequireTenantId()).to.equal('abcd_001');
113+
});
114+
115+
it('strips f_ecom_ prefix from tenant ID', async () => {
116+
stubParse(command, {'client-id': 'test-client', 'tenant-id': 'f_ecom_abcd_001'});
117+
await command.init();
118+
119+
expect(command.testRequireTenantId()).to.equal('abcd_001');
120+
});
121+
122+
it('throws error when no tenant ID provided', async () => {
123+
stubParse(command);
124+
await command.init();
125+
126+
const errorStub = sinon.stub(command, 'error').throws(new Error('Expected error'));
127+
128+
try {
129+
command.testRequireTenantId();
130+
} catch {
131+
// Expected
132+
}
133+
134+
expect(errorStub.called).to.be.true;
135+
});
136+
});
137+
103138
describe('getDefaultClientId', () => {
104139
it('returns undefined by default (no fallback)', async () => {
105140
stubParse(command);

0 commit comments

Comments
 (0)