# Sf B2c Sfra

> Build B2C Commerce storefronts with SFRA (Storefront Reference Architecture) — cartridge overlay system, MVC pattern, app_storefront_base, module.superModule inheritance, middleware chain, and site-specific customizations. Use when developing SFRA-based storefronts.

- Skill: `orcaqubits/sf-b2c-sfra` (Agent Skill)
- Install (CLI): `npx skillmds@latest add orcaqubits/sf-b2c-sfra`
- Raw SKILL.md: https://api.skillmd.com/api/skills/orcaqubits/sf-b2c-sfra/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: OrcaQubits (https://skillmd.com/u/orcaqubits)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/orcaqubits/sf-b2c-sfra

---


# Salesforce B2C Commerce SFRA Development

## Before Writing Code

**Fetch live docs:**
1. WebFetch `github.com/SalesforceCommerceCloud/storefront-reference-architecture` for SFRA source
2. Web-search `site:developer.salesforce.com SFRA architecture MVC` for MVC patterns
3. Web-search `site:developer.salesforce.com SFRA cartridge overlay` for overlay best practices
4. Web-search `site:developer.salesforce.com module.superModule` for extension patterns
5. Web-search `site:developer.salesforce.com SFRA getting started` for latest docs

## Conceptual Architecture

### SFRA Overview

SFRA (Storefront Reference Architecture) is the reference implementation for B2C Commerce storefronts:

- **Server-side MVC** -- Models, Views (ISML), Controllers
- **Cartridge overlay system** -- stack custom cartridges on top of base
- **module.superModule** -- extend base functionality without copying code
- **Client-side build** -- Webpack bundles JS and SCSS
- **Page Designer** -- visual page building with reusable components

### Four Key Principles

| Principle | Rule |
|-----------|------|
| **Overlay** | Never modify `app_storefront_base` -- create custom cartridges that layer on top |
| **Extend** | Use `module.superModule` to inherit and augment, not replace |
| **Hooks** | Use commerce hooks for order, payment, and shipping customization |
| **Services** | Use the Service Framework for external integrations (payment gateways, ERP) |

### Cartridge Path Resolution

The cartridge path (configured in Business Manager) resolves files left-to-right. The **leftmost cartridge wins**.

Example path: `app_custom:app_storefront_base`
- Request for `controllers/Product.js` checks `app_custom` first, falls back to `app_storefront_base`
- Templates, models, and scripts follow the same resolution

### Cartridge Directory Structure

```
app_custom/cartridge/
├── controllers/        # Route handlers
├── models/             # Data models
├── scripts/            # Helpers, services
├── templates/          # ISML templates
├── experience/         # Page Designer
└── client/default/     # JS + SCSS source (Webpack)
```

### module.superModule

`module.superModule` resolves to the next cartridge in the path that provides the same module. This is how you extend without duplicating:

- **Controllers**: `var base = module.superModule; server.extend(base);` then use `append`/`prepend`/`replace`
- **Models**: Call base constructor with `base.call(this, apiProduct, options)`, then add properties
- **Scripts**: Import base, extend functions, re-export with spread

### MVC Pattern

| Layer | Location | Role |
|-------|----------|------|
| **Controller** | `controllers/*.js` | Route handling via `server` module |
| **Model** | `models/**/*.js` | Transform API data to view-friendly objects |
| **View** | `templates/default/**/*.isml` | ISML templates for HTML rendering |
| **Client JS** | `client/default/js/` | Browser-side behavior (Webpack bundled) |
| **SCSS** | `client/default/scss/` | Styles (compiled to CSS) |

### Extend vs Replace Controllers

| Approach | When | Trade-off |
|----------|------|-----------|
| `server.extend(base)` + `append` | Adding data, logging, analytics | Keeps base logic; auto-receives base updates |
| `server.replace('Route', fn)` | Fundamentally different logic | You own the entire implementation; no base updates |

Prefer `extend` + `append` in nearly all cases. Only `replace` when the base logic is wrong for your use case.

### Client-Side Build

SFRA uses Webpack to build client assets from `client/default/js/` and `client/default/scss/`. Output goes to `cartridge/static/default/`. Client JS can extend base modules:

```javascript
// Pattern: Extend base client module
var base = require('base/product/detail');
// Fetch live docs for base module API
```

### Site Preferences and Custom Objects

- **Site Preferences**: `Site.getCurrent().getCustomPreferenceValue('prefName')` -- store-level configuration
- **Custom Objects**: `CustomObjectMgr.getCustomObject('Type', 'key')` -- custom data structures
- Both are managed in Business Manager and accessed via `dw.*` API

## Best Practices

### Cartridge Overlay
- Never modify `app_storefront_base`
- Name custom cartridges consistently: `app_custom_[sitename]` or `int_custom_[feature]`
- Use `module.superModule` to extend -- avoid code duplication
- Test overlays after base cartridge updates

### Controllers and Models
- Use `server.extend()` to inherit base routes
- Keep controllers thin -- move logic to models and scripts
- Call base model constructor, then add properties
- Always call `next()` in middleware chain

### Templates and Client Code
- Use `<isinclude>` for reusable components
- Use resource bundles for all text: `Resource.msg('key', 'bundle', null)`
- Import and extend base client JS modules
- Minimize jQuery -- prefer vanilla JS for performance

### Security and Performance
- Use `Transaction.wrap()` for all database writes
- Encode output in templates to prevent XSS
- Use CSRF tokens for state-changing operations
- Cache expensive operations via `CacheMgr`

Fetch the SFRA GitHub repository, developer documentation, and module.superModule guide for exact patterns, API references, and best practices before implementing.

