Your metadata is part of the editor's type model. The language server reads local SFCC metadata XML and generates declarations for system-object custom attributes, site preferences, and custom objects. The same definitions feed completion, hover, diagnostics, navigation, and attribute usage tracking.
From Product XML to script completion
Add a custom attribute to a local metadata file:
<?xml version="1.0" encoding="UTF-8"?>
<metadata xmlns="http://www.demandware.com/xml/impex/metadata/2006-10-31">
<type-extension type-id="Product">
<custom-attribute-definitions>
<attribute-definition attribute-id="badgeLabel">
<display-name xml:lang="x-default">Badge label</display-name>
<description xml:lang="x-default">Short label for the product tile.</description>
<type>string</type>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
</attribute-definition>
</custom-attribute-definitions>
</type-extension>
</metadata>var ProductMgr = require('dw/catalog/ProductMgr');
function getBadge(id) {
var product = ProductMgr.getProduct(id);
return product ? product.custom.badgeLabel || '' : '';
}
module.exports = { getBadge: getBadge };Save the XML and allow metadata indexing to finish. In the script, invoke completion after product.custom.. Hover badgeLabel to see its generated type and metadata description. Go to Definition takes you back to the attribute's XML definition.
Site preferences
Attributes declared on SitePreferences generate typed preference access. With a boolean attribute named showProductBadge, both the custom-preferences object and the preference getter become useful entry points:
var Site = require('dw/system/Site');
var site = Site.getCurrent();
var enabled = site.getCustomPreferenceValue('showProductBadge');
var samePreference = site.getPreferences().custom.showProductBadge;The generator also contributes overloads for setCustomPreferenceValue. Completion and signatures use the locally defined preference names and their types. A generated declaration describes an attribute; it does not fetch the current preference value from a sandbox.
Custom objects and typed keys
A custom-object type definition adds type-specific overloads to CustomObjectMgr. For a local StoreNotice type with a string key and a string message attribute:
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var notice = CustomObjectMgr.getCustomObject('StoreNotice', 'homepage');
if (notice) {
var message = notice.custom.message;
}The literal type ID selects the generated object shape, and the key definition contributes its accepted key type. The generator covers describe, createCustomObject, getCustomObject, getAllCustomObjects, queryCustomObject, queryCustomObjects, and remove.
Iterators retain the custom-object shape for their elements. Keep ordinary SFCC iterator and transaction rules when using those APIs; generated types do not create data or execute transactions.
Attribute types and documentation
| Metadata detail | Editor behavior |
|---|---|
| Attribute ID and object type | Members belong to the corresponding object rather than one untyped attribute bag. |
| String, boolean, numeric, date, and other supported XML types | The generated declaration uses the corresponding mapped script type. |
| Enumerated string or integer values | The generated EnumValue type can preserve the allowed literal values. |
| Multi-select enumeration | The type represents a read-only collection of enum values, rather than a single primitive. |
| Display name and description | They appear in generated JSDoc and completion or hover details. |
| Attribute group and source location | Generated documentation links back to the local metadata and group. |
Use the generated declaration to inspect the exact type, including nullability and SFCC wrappers. An enum attribute is not simply a JavaScript string because its XML values are strings.
Trace types back to XML
Start at a script access
Invoke Go to Definition on a resolved custom attribute or supported preference access. The metadata mapping connects the generated member to the original XML.
Find its consumers
Use Find All References on a recognized attribute access or definition. Metadata XML also shows an attribute-usage CodeLens after indexing. Results come from the indexed project and recognized access patterns; dynamically constructed names can be missed.
Inspect the generated declaration
With a metadata document active, run Open Generated Metadata Types. This is a separate editor action from the XML usage lens and helps explain the type used by the checker.
The extension writes generated files under .intellij-sfcc/generated/ in the first workspace folder:
| File | Contents |
|---|---|
so-types.d.ts | System-object custom attributes and site-preference overloads |
co-types.d.ts | Custom-object attributes, key types, and manager overloads |
form-types.d.ts | Form declarations; see Forms & fields |
Edit the source XML rather than these generated declarations. They are regenerated as metadata changes; no separate generator command is needed.
When an attribute is missing
Check that its definition is available in local workspace XML, the object type-id and attribute-id match your code, and indexing has completed. Then inspect the generated declaration to distinguish a missing definition from an incorrectly typed receiver. For example, an arbitrary object named product does not acquire the dw.catalog.Product type from its variable name.
Metadata available only in Business Manager must first be available to the local project workflow. The editor's type model is not a live guarantee of sandbox metadata. Configuration & troubleshooting covers the shared checks.