b2c-localization

This skill guides you through localizing B2C Commerce storefronts for multiple languages and regions.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "b2c-localization" with this command: npx skills add salesforcecommercecloud/b2c-developer-tooling/salesforcecommercecloud-b2c-developer-tooling-b2c-localization

Localization Skill

This skill guides you through localizing B2C Commerce storefronts for multiple languages and regions.

Overview

B2C Commerce supports localization through:

Component Approach

Templates Single template set + resource bundles

Forms Shared definitions + locale-specific labels

Static content Locale-specific folders

Product data Localizable attributes

Locale Format

Locales follow ISO standards: {language}_{country}

Format Example Description

en

English Language only

en_US

English/USA Language + country

fr_CA

French/Canada Language + country

de_DE

German/Germany Language + country

Resource Bundles

Directory Structure

/cartridge /templates /resources account.properties # Default (English) checkout.properties /fr account.properties # French checkout.properties /de account.properties # German checkout.properties /fr_CA account.properties # French Canadian

Property File Format

account.properties (default):

##############################################

Account Pages

############################################## account.title=My Account account.greeting=Welcome back account.logout=Sign Out

Account Dashboard

dashboard.title=Dashboard dashboard.orders=Order History dashboard.addresses=Address Book dashboard.wishlist=Wishlist

Profile

profile.title=Profile profile.firstName=First Name profile.lastName=Last Name profile.email=Email Address profile.save=Save Changes

account_fr.properties (French):

account.title=Mon compte account.greeting=Bon retour account.logout=Se déconnecter

dashboard.title=Tableau de bord dashboard.orders=Historique des commandes dashboard.addresses=Carnet d'adresses dashboard.wishlist=Liste de souhaits

profile.title=Profil profile.firstName=Prénom profile.lastName=Nom profile.email=Adresse e-mail profile.save=Enregistrer les modifications

Using Resources in Templates

<!-- Simple message --> <h1>${Resource.msg('account.title', 'account', null)}</h1>

<!-- With fallback --> <p>${Resource.msg('account.greeting', 'account', 'Welcome')}</p>

<!-- With parameters --> <p>${Resource.msgf('cart.items', 'cart', null, cartCount)}</p>

Resource.msg() parameters:

  • Key name

  • Bundle name (filename without extension)

  • Default value (null = use key if not found)

Parameterized Messages

Property:

cart.itemCount=You have {0} items in your cart greeting.personalized=Hello, {0} {1}! order.confirmation=Order #{0} placed on {1}

Template:

${Resource.msgf('cart.itemCount', 'cart', null, itemCount)} ${Resource.msgf('greeting.personalized', 'common', null, firstName, lastName)}

Locale Fallback

B2C Commerce uses a fallback chain: fr_CA → fr → default

Example: Requesting fr_CA :

  • Look in /resources/fr_CA/account.properties

  • If not found, look in /resources/fr/account.properties

  • If not found, look in /resources/account.properties

Static Files

Directory Structure

/cartridge /static /default /css style.css /images logo.png buttons/ submit.png /js main.js /fr /images buttons/ submit.png # French text on button /de /images buttons/ submit.png # German text on button

Referencing Static Files

<!-- Uses locale-specific version if available --> <img src="${URLUtils.staticURL('/images/buttons/submit.png')}" alt="Submit"/>

<!-- CSS (usually not localized) --> <link rel="stylesheet" href="${URLUtils.staticURL('/css/style.css')}"/>

Forms Localization

Form Definition

<?xml version="1.0" encoding="UTF-8"?> <form xmlns="http://www.demandware.com/xml/form/2008-04-19"> <field formid="email" label="form.email.label" type="string" mandatory="true" missing-error="form.email.required" parse-error="form.email.invalid"/> </form>

Resource Bundle

forms.properties:

form.email.label=Email Address form.email.required=Email is required form.email.invalid=Please enter a valid email address

forms_fr.properties:

form.email.label=Adresse e-mail form.email.required=L'email est requis form.email.invalid=Veuillez entrer une adresse e-mail valide

URL Localization

Locale-Aware URLs

<!-- Current locale URL --> <a href="${URLUtils.url('Product-Show', 'pid', 'ABC123')}">View Product</a>

<!-- Specific locale URL --> <a href="${URLUtils.url(new URLAction('Product-Show', 'MySite', 'fr'))}"> Voir le produit </a>

Language Switcher

<isscript> var Site = require('dw/system/Site'); var URLAction = require('dw/web/URLAction'); var URLUtils = require('dw/web/URLUtils'); var Locale = require('dw/util/Locale'); </isscript>

<ul class="language-switcher"> <isloop items="${Site.current.allowedLocales}" var="localeId"> <isscript> var locale = new Locale(localeId); var url = URLUtils.url(new URLAction('Home-Show', Site.current.ID, localeId)); </isscript> <li class="${request.locale == localeId ? 'active' : ''}"> <a href="${url}">${locale.displayLanguage}</a> </li> </isloop> </ul>

Controller Localization

Accessing Current Locale

var Locale = require('dw/util/Locale');

server.get('Show', function (req, res, next) { var currentLocale = Locale.getLocale(req.locale.id);

res.render('mytemplate', {
    locale: req.locale.id,
    language: currentLocale.language,
    country: currentLocale.country,
    displayLanguage: currentLocale.displayLanguage,
    displayCountry: currentLocale.displayCountry
});
next();

});

Locale-Specific Logic

server.get('Checkout', function (req, res, next) { var locale = req.locale.id;

// Locale-specific date format
var dateFormat = locale.startsWith('en_US') ? 'MM/dd/yyyy' : 'dd/MM/yyyy';

// Locale-specific content
var termsContentId = 'terms-' + locale.replace('_', '-').toLowerCase();

res.render('checkout', {
    dateFormat: dateFormat,
    termsContentId: termsContentId
});
next();

});

Email Templates

Setting Locale

var Template = require('dw/util/Template'); var HashMap = require('dw/util/HashMap'); var Mail = require('dw/net/Mail');

function sendOrderConfirmation(order, locale) { var template = new Template('mail/orderconfirmation', locale); var model = new HashMap(); model.put('order', order);

var content = template.render(model).text;

var mail = new Mail();
mail.addTo(order.customerEmail);
mail.setFrom('orders@example.com');
mail.setSubject(Resource.msg('email.order.subject', 'email', null));
mail.setContent(content, 'text/html', 'UTF-8');
mail.send();

}

Currency Formatting

Currency is tied to locale:

var Money = require('dw/value/Money'); var StringUtils = require('dw/util/StringUtils');

// Format with locale var price = new Money(99.99, 'USD'); var formatted = StringUtils.formatMoney(price); // Uses current locale

// In template <isprint value="${product.priceModel.price}" style="CURRENCY"/>

Date Formatting

var StringUtils = require('dw/util/StringUtils'); var Calendar = require('dw/util/Calendar');

var date = new Calendar(); var formatted = StringUtils.formatCalendar(date, 'yyyy-MM-dd'); // ISO format var localized = StringUtils.formatCalendar(date, 'MMMM d, yyyy'); // Locale-aware

Best Practices

  • Use UTF-8 for all property files (required for non-ASCII characters)

  • Organize bundles by page/feature not by language

  • Keep keys descriptive - account.profile.firstName not label1

  • Use parameters for dynamic values - don't concatenate strings

  • Test all locales - ensure fallback works correctly

  • Don't hardcode text in templates or scripts

Detailed Reference

  • Localization Patterns - Complete patterns and examples

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

b2c-slas-auth-patterns

No summary provided by upstream source.

Repository SourceNeeds Review