SFCC Contracts

Completion and navigation for the strings that tie SFCC code together - routes, templates, resource keys, hooks, forms, custom attributes and preferences

A lot of SFCC code is held together by strings: 'Cart-Show', 'cart/cart', 'button.checkout', 'app.payment.processor.basic_credit'. To plain JavaScript they are just text. Intellij SFCC knows what each one points to, so it completes them from your project and Cmd+Click (Ctrl+Click) takes you to the route, template, bundle key, hook, form or attribute behind them

Resource.msg keys complete from every .properties bundle with the locales that define them. Accepting fills in the bundle name too

Routes and controllers

CallThe stringCompletes
URLUtils.url, URLUtils.https, URLUtils.http, URLUtils.absThe full route, for example Cart-ShowEvery route of every linked cartridge: SFRA controllers, SiteGenesis exports.<Name> controllers and pipeline start nodes
server.append, server.prepend, server.replaceA route name of the same controller, for example ShowThe routes of the controller you extend
server.get, server.post, server.useThe route name you defineNothing, but Cmd+Click lists every other definition, append, prepend and replace of that route
app_custom/cartridge/controllers/Cart.js
'use strict';

var server = require('server');
var URLUtils = require('dw/web/URLUtils');

server.extend(module.superModule);

server.append('Show', function (req, res, next) {
    res.setViewData({ continueUrl: URLUtils.url('Search-Show', 'cgid', 'root').toString() });
    next();
});

module.exports = server.exports();

Here 'Show' completes the routes of the original Cart.js, and 'Search-Show' completes from every controller in the project. Route items carry the route icon . To find a route by name from anywhere, use the SFCC Routes tab of Search Everywhere

Templates

CallTemplate argument
res.render, app.getView().renderFirst
ISML.renderTemplateFirst
new Template(...)First
renderTemplateHelper.getRenderedHtmlSecond
emailHelpers.sendEmailSecond

Template paths complete relative to the templates/<locale> folder of each cartridge, without the .isml extension. A call with a known template gets a gutter icon, Navigate to template. When the template exists in several cartridges, the icon opens Choose Declaration with every copy

res.render('cart/cart', { basket: basketModel });

Resource bundles

Resource.msg and Resource.msgf complete keys from every .properties bundle in your linked cartridges. Each item lists the locales that define it, default first, and the right side shows the cartridge and bundle, for example app_storefront_base:cart

var Resource = require('dw/web/Resource');

var label = Resource.msg('button.checkout', 'cart', null);
var count = Resource.msgf('label.number.items.in.cart', 'cart', null, 3);
  • Accept a key in an empty Resource.msg('') and the plugin fills the whole call: the key, its bundle and null as the default. For Resource.msgf it leaves the cursor where the format arguments go
  • The second argument completes bundle names
  • Cmd+Click on a key opens its entries in every locale file

Hooks

HookMgr.callHook and HookMgr.hasHook complete the hook names registered in your cartridges' hooks.json files. Each item shows the script it points to and the cartridge that registers it. The second argument of callHook completes the functions that the hook's scripts export

var HookMgr = require('dw/system/HookMgr');

if (HookMgr.hasHook('app.payment.processor.basic_credit')) {
    HookMgr.callHook('app.payment.processor.basic_credit', 'Authorize', order.orderNo, paymentInstrument, paymentProcessor);
}

SFRA's hooksHelper('app.customer.subscription', 'subscribeTo', ...) works the same way. Cmd+Click on the hook name opens its entry in hooks.json, and on the function name opens the exported function. The hooks.json side, with the 311 built-in hook names, is on XML & JSON Validation

Forms

server.forms.getForm('profile') completes the form IDs from cartridge/forms and opens the form XML on Cmd+Click. The returned form is typed from that XML, so its groups and fields complete like regular objects

var profileForm = server.forms.getForm('profile');
var email = profileForm.customer.email.value;

In SiteGenesis-style code, session.forms. completes the form names. Resource keys, includes and validation inside the form XML are covered on XML & JSON Validation

Custom attributes and preferences

The plugin reads your metadata XML and completes custom attribute IDs where SFCC code uses them

CodeCompletes
product.custom., product.custom['...'], product.getCustom().Custom attributes of the object's system type, for example Product
Site.getCurrent().getCustomPreferenceValue('...')Custom site preferences
CustomObjectMgr.getCustomObject('...', key)Custom object type IDs
.custom. on a custom objectAttributes of custom object types

Each item shows the attribute type and group, and the metadata file it comes from on the right. Cmd+Click opens the attribute definition in that file

Metadata is read from files named system-objecttype-extensions.xml or custom-objecttype-definitions.xml and from any XML file in a meta or metadata folder, for example the meta folder of your site import data. Keep that data in the project to get these completions

.custom. completes only when the IDE knows the object's type. If it doesn't, add the dw. type with JSDoc, see API & Types

What isn't checked

The plugin completes and resolves these strings but doesn't mark unknown ones as errors. A misspelled route, template or key compiles and fails only at runtime. A quick check is Cmd+Click: a string that resolves opens its target, one that doesn't goes nowhere

Troubleshooting

SymptomWhat to do
A route is missing from URLUtils.urlIts controller is in a cartridge that isn't linked, or indexing is still running
server.append('') lists nothingAdd server.extend(module.superModule) and make sure another linked cartridge has a controller with the same name
No Navigate to template iconThe template path doesn't match a file in templates/<locale> of a linked cartridge
A resource key is missingThe bundle is in a cartridge that isn't linked, or under a folder other than templates/resources
No custom attributes after .custom.The object isn't typed, or the metadata XML isn't in the project. Check the file name or meta folder rules above
A hook name is missingIt is registered in a hooks.json of a cartridge that isn't linked

On this page