Digital Script is ES5 plus the Rhino forms B2C Commerce runs. Newer syntax depends on the compatibility mode of the code version, and the plugin marks what that mode can't run, with a fix to the older form
for..of, template literals and arrow functions are errors that name the mode that runs them. Optional chaining runs in no B2C Commerce mode, so it is an error whatever the modeRhino forms
These parse as code in .ds files and server .js files:
| Form | Example |
|---|---|
for each...in | for each (var p in products) {} |
| Conditional catch | catch (e if e instanceof ReferenceError) |
XML literals with {} holes, and XML lists | <amount currency={currency}>{total}</amount>, <><a/><b/></> |
| An XML declaration before a literal | <?xml version="1.0"?><feed/> |
| E4X members | .@id, ..item, ns::name, .*, .@*, .@['attribute-id'], .(@id == 'y') |
default xml namespace | default xml namespace = new Namespace('...'); |
| Type annotations | var basket : Basket, function total() : Number |
var mode = response.fraud.@mode, isDefault = node.@['default'];
var all = xml.*, items = xml..item, deep = xml..@id, qualified = xml.ns::name;
delete attributes.item.(@id == 'y')[0];
default xml namespace = new Namespace('http://www.demandware.com/xml/impex/catalog/2006-10-31');Templates parse E4X members in ${...} and <isscript> too, but not XML literals. Unicode format characters such as a zero-width space count as whitespace, as Rhino reads them
Expression closures, legacy generators, let blocks and array comprehensions don't parse yet
Rhino checks
| Check | Level | Message | Fix |
|---|---|---|---|
for each with of | Error, always on | invalid for each loop | Remove 'each', Use 'in' |
| 'each' in a for (;;) loop | Warning | 'each' has no effect in a for (;;) loop | Remove 'each' |
| Rhino-only syntax that ES2015 replaces | Weak warning, off by default | 'for each' is a Rhino extension; ES2015 code uses for...of, A conditional catch clause is a Rhino extension; ES2015 code tests the error in the catch block | None |
To move a loop to ES2015, use the Convert to 'for...of' loop intention, see Intentions
Compatibility mode
B2C Commerce runs each code version in a compatibility mode, set in Business Manager › Administration › Site Development › Code Deployment. Modes before 21.2 run Rhino 1.7R5, 21.2 runs Rhino 1.7.13 and 22.7 runs Rhino 1.7.14
| Mode | Adds |
|---|---|
| 10.4 to 19.10 | ES5 plus let, const, array destructuring and for each |
| 21.2 | Arrow functions, for...of, generator functions, shorthand methods, object destructuring |
| 22.7 | Shorthand properties, template literals, the ** operator, BigInt literals |
No mode runs classes, generator methods, default values, rest parameters, spread syntax, computed property names, async functions, object rest and spread, optional chaining, the ?? operator or logical assignment. Every mode runs let, const, array destructuring, for each, getters and setters, and type annotations, so this check never reports them. 'let' or 'const' in server code still asks for var, see let and const
Where the mode comes from
The Digital Script page
The mode picked in Settings › Languages & Frameworks › Digital Script › Script compatibility mode, saved with the project
The old ISML option
The mode the ISML page stored before 2026.3, until you pick one on the Digital Script page
The activated code version
With Not set, the mode of the code version last activated from the B2C explorer with Activate Code Version or Activate and Select Code Version, see Activate a code version. It's stored for you only, and the comment under the option names it
No mode yet
Until a code version is activated, Not set reports only the syntax no mode supports
A new mode applies without a restart, in every open script and template
Unsupported syntax
Script syntax the compatibility mode does not support is an error, free, and works while the IDE indexes. It names the mode that runs the syntax:
Compatibility mode 19.10 does not support arrow functions (21.2 or later)No B2C compatibility mode supports optional chaining
| Fix | On | Not offered when |
|---|---|---|
| Convert to 'for each' loop | for...of | The loop declares more than one variable, or it's for await |
| Convert to string concatenation | A template literal | The template is tagged |
| Convert to function expression | An arrow function | The body uses this, arguments or super, or the arrow is async or a generator |
importPackage(dw.util);
function labels(items : List) : Array {
var out = [];
for (var item of items) {
out.push(`${item.name}: ${item.price}`);
}
return out.map((label) => label.trim());
}importPackage(dw.util);
function labels(items : List) : Array {
var out = [];
for each (var item in items) {
out.push(item.name + ': ' + item.price);
}
return out.map(function (label) { return label.trim(); });
}Templates get the same check for ${...} and <isscript>, see ISML inspections
IDE suggestions that follow the mode
The IDE's own suggestions that write syntax the mode can't run are hidden in Digital Script: arrow functions, template literals, for...of loops, shorthand properties, classes, async functions and object destructuring. With Not set, a form some mode runs counts as runnable. Convert to let and Convert to const are hidden too while 'let' or 'const' in server code runs, which needs a license and is on by default. Without it, only Convert to const is hidden, and only where the const would run differently on Rhino: in a loop, or beside another declaration of the name. Client .js files keep every suggestion
Intentions that turn require into ES import or module.exports into export are hidden in Digital Script, since the server runs neither