Guide for creating storefront controllers in Salesforce B2C Commerce (SFRA and classic patterns)
View on GitHubSalesforceCommerceCloud/b2c-developer-tooling
b2c
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/SalesforceCommerceCloud/b2c-developer-tooling/blob/main/plugins/b2c/skills/b2c-controllers/SKILL.md -a claude-code --skill b2c-controllersInstallation paths:
.claude/skills/b2c-controllers/# Controllers Skill
This skill guides you through creating storefront controllers for Salesforce B2C Commerce. Controllers handle HTTP requests and render responses for the storefront.
## Overview
Controllers are JavaScript modules that handle storefront requests. A controller URL has this structure:
```
https://{domain}/on/demandware.store/Sites-{SiteName}-Site/{locale}/{ControllerName}-{FunctionName}
```
**Example:** `https://example.com/on/demandware.store/Sites-RefArch-Site/en_US/Home-Show`
## Two Controller Patterns
B2C Commerce supports two controller patterns:
| Pattern | When to Use | Module Style |
|---------|-------------|--------------|
| **SFRA** | Storefront Reference Architecture sites | `server` module with middleware |
| **Classic** | Non-SFRA sites, simple APIs | Direct exports with `.public = true` |
**SFRA is recommended** for most storefront development. Classic controllers are useful for simple endpoints or non-SFRA projects.
## File Location
Controllers reside in the cartridge's `controllers` directory:
```
/my-cartridge
/cartridge
/controllers
Home.js # URL: Home-{function}
Product.js # URL: Product-{function}
Cart.js # URL: Cart-{function}
```
**Naming:** Controller filename becomes the URL prefix. `Home.js` handles `Home-*` requests.
## SFRA Controllers (Recommended)
SFRA controllers use the `server` module for routing and middleware:
```javascript
'use strict';
var server = require('server');
// Handle GET request
server.get('Show', function (req, res, next) {
res.render('home/homepage');
next();
});
// Handle POST request
server.post('Subscribe', function (req, res, next) {
var email = req.form.email;
// Process subscription...
res.json({ success: true });
next();
});
module.exports = server.exports();
```
### Request Object (req)
```javascript
req.querystring // Query parameters: ?q=shoes -> req.querystring.q
r