Syntax & Compatibility Mode

Rhino syntax in Digital Script, from for each and E4X to XML literals and type annotations, and the compatibility mode check for your code version

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

With the mode at 19.10, 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 mode

Rhino forms

These parse as code in .ds files and server .js files:

FormExample
for each...infor each (var p in products) {}
Conditional catchcatch (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 namespacedefault xml namespace = new Namespace('...');
Type annotationsvar basket : Basket, function total() : Number
cartridge/scripts/export/Feed.ds
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

CheckLevelMessageFix
for each with ofError, always oninvalid for each loopRemove 'each', Use 'in'
'each' in a for (;;) loopWarning'each' has no effect in a for (;;) loopRemove 'each'
Rhino-only syntax that ES2015 replacesWeak 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 blockNone

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

ModeAdds
10.4 to 19.10ES5 plus let, const, array destructuring and for each
21.2Arrow functions, for...of, generator functions, shorthand methods, object destructuring
22.7Shorthand 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
FixOnNot offered when
Convert to 'for each' loopfor...ofThe loop declares more than one variable, or it's for await
Convert to string concatenationA template literalThe template is tagged
Convert to function expressionAn arrow functionThe body uses this, arguments or super, or the arrow is async or a generator
Before, mode 19.10
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());
}
After the three fixes
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

On this page