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
In metadata XML, the first attribute definition shows Indexing usages… while usages are collected, then each definition gets an N usages lens. Click it to peek every reference to the attribute
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
Metadata in VS Code
| Feature | What you get |
|---|---|
| XSD validation | Metadata and other import XML is checked against the 53 bundled B2C Commerce schemas, including unsaved text as you type, see XML validation |
| Usage lens and colors | The N usages lens above, and usage colors set by intellij-sfcc.metadataAttributes.colorMode: "off", "unusedOnly" (default) or "heatmap", see Settings |
Typed .custom | Custom attributes, site preferences and custom objects complete, hover and lead back to their XML, as described above |
| SFCC MCP tools | intellijsfcc.xml.schema.contract and intellijsfcc.xml.validate for schema-safe XML edits, intellijsfcc.metadata.object.search and intellijsfcc.metadata.object.details for objects, attributes, groups, enum values and their XML locations, see SFCC MCP |
VS Code has no metadata design editor and no site archive tool window, so you edit metadata as XML. JetBrains IDEs have both: the Metadata Editor and the B2C Metadata tool window
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