commerce-lwc-components

Use this skill when building or customizing Lightning Web Components for B2B Commerce or D2C LWR storefronts — product display tiles, cart line-item components, checkout step components, wishlist buttons, and product comparison widgets that rely on Commerce Storefront wire adapters from the commerce namespace. NOT for standard LWC development outside a Commerce store context, not for Aura-based Community Builder components, and not for legacy B2B Commerce (CloudCraze) Aura widgets.

Best use case

commerce-lwc-components is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use this skill when building or customizing Lightning Web Components for B2B Commerce or D2C LWR storefronts — product display tiles, cart line-item components, checkout step components, wishlist buttons, and product comparison widgets that rely on Commerce Storefront wire adapters from the commerce namespace. NOT for standard LWC development outside a Commerce store context, not for Aura-based Community Builder components, and not for legacy B2B Commerce (CloudCraze) Aura widgets.

Teams using commerce-lwc-components should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/commerce-lwc-components/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/lwc/commerce-lwc-components/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/commerce-lwc-components/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How commerce-lwc-components Compares

Feature / Agentcommerce-lwc-componentsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use this skill when building or customizing Lightning Web Components for B2B Commerce or D2C LWR storefronts — product display tiles, cart line-item components, checkout step components, wishlist buttons, and product comparison widgets that rely on Commerce Storefront wire adapters from the commerce namespace. NOT for standard LWC development outside a Commerce store context, not for Aura-based Community Builder components, and not for legacy B2B Commerce (CloudCraze) Aura widgets.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Commerce LWC Components

Use this skill when an LWC component must read or mutate product, cart, wishlist, or checkout data inside a B2B Commerce or D2C LWR storefront. It covers Commerce Storefront wire adapters (`commerce/*` modules), CSP capability requirements, Experience Builder registration, and SFDX deployment of storefront components.

---

## Before Starting

Gather this context before working on anything in this domain:

- **Store type and template name.** B2B Commerce and D2C stores expose overlapping but non-identical wire adapters. Confirm which store template is in use (`b2b` vs `b2c`/`d2c`) before choosing adapters.
- **Salesforce release.** Commerce Storefront wire adapters have been expanded across releases. Adapters like `getCartItems` (from `commerce/cartApi`) and `getProduct` (from `commerce/productApi`) have had breaking changes between Winter and Summer releases. Always confirm adapter availability for the target org version.
- **LWS vs Locker status.** LWR-based store templates run with both Lightning Web Security (LWS) and Lightning Locker disabled. Components behave differently from App Builder LWC: `eval`, cross-origin iframes, and some DOM globals that are blocked in standard LWC contexts may be available — but security must be implemented explicitly rather than relying on the framework enforcing it.
- **Deployment path.** Commerce storefront components are deployed via SFDX metadata (not Change Sets). The component must be in `force-app/main/default/lwc/` and surfaced in Experience Builder via the component meta XML.

---

## Core Concepts

### Commerce Storefront Wire Adapters (`commerce/*`)

Custom LWC components in B2B/D2C LWR stores bind to product, cart, and wishlist data using wire adapters imported from the `commerce` namespace — for example `commerce/productApi`, `commerce/cartApi`, `commerce/wishlistApi`. These are NOT the same as `lightning/uiRecordApi` or `lightning/uiObjectInfoApi`. Using standard LDS adapters inside a store component will either silently return no data or throw import errors at runtime, because LDS is not available in the LWR storefront rendering context.

Wire adapters from the `commerce` namespace resolve store context automatically: the component does not need to pass a store ID or buyer group ID — these come from the runtime storefront context injected by the LWR framework.

Key adapters:
- `getProduct` from `commerce/productApi` — resolves product fields, pricing, and media for a given product ID.
- `getCartItems` and `addItemToCart` from `commerce/cartApi` — reads cart line items and mutates the active cart.
- `getWishlist` and `addToWishlist` from `commerce/wishlistApi` — reads and modifies the buyer's wishlist.
- `getProductPrice` from `commerce/productApi` — resolves negotiated and list prices for a buyer's account.

### lightningCommunity__RelaxedCSP Capability

LWR storefront templates disable both Lightning Locker and Lightning Web Security. A custom LWC that is deployed into this context must declare `lightningCommunity__RelaxedCSP` in the `capabilities` array of its `.js-meta.xml` file. Without this declaration, the component may render inconsistently across store pages or fail silently on certain page types. This is not optional: it signals to the Experience Cloud runtime that the component has been authored with awareness that standard LWC sandbox protections are absent.

Omitting `lightningCommunity__RelaxedCSP` is the most common reason a component that works in Experience Builder preview fails when deployed to a live store.

### Experience Builder Registration and Design Properties

A component must be exposed in Experience Builder to be drag-and-droppable onto store pages. This requires:
1. Setting `isExposed: true` in the `.js-meta.xml`.
2. Declaring at least one target inside `<targets>` — typically `lightningCommunity__Page` or a specific Commerce store page target.
3. Optionally declaring `<targetConfigs>` to expose design-time properties (e.g., product tile image size) that store admins can configure per page.

Components registered without the correct `<targets>` entries will not appear in the Experience Builder component panel even if the metadata deployment succeeds.

---

## Common Patterns

### Pattern 1: Product Display Tile with Storefront Wire Adapter

**When to use:** Building a custom product card that shows product name, image, description, and negotiated price inside a B2B or D2C LWR store product list page.

**How it works:**

```javascript
// productTile.js
import { LightningElement, api, wire } from 'lwc';
import { getProduct } from 'commerce/productApi';
import { getProductPrice } from 'commerce/productApi';

export default class ProductTile extends LightningElement {
    @api recordId; // product ID passed by the store page

    @wire(getProduct, { productId: '$recordId', fields: ['ProductCode', 'Description', 'Name'] })
    product;

    @wire(getProductPrice, { productId: '$recordId' })
    price;

    get productName() {
        return this.product?.data?.fields?.Name?.value;
    }

    get negotiatedPrice() {
        return this.price?.data?.negotiatedPrice;
    }
}
```

The `.js-meta.xml` must include:
```xml
<capabilities>
    <capability>lightningCommunity__RelaxedCSP</capability>
</capabilities>
<targets>
    <target>lightningCommunity__Page</target>
</targets>
```

**Why not the alternative:** Using `@wire(getRecord, { recordId: '$recordId', fields: [...] })` from `lightning/uiRecordApi` will not work. The LWR storefront runtime does not load LDS modules, so the adapter returns no data and no error, silently breaking the component.

### Pattern 2: Cart Mutation with Imperative Call

**When to use:** Building an "Add to Cart" button that adds a product and quantity to the active buyer cart.

**How it works:**

```javascript
// addToCartButton.js
import { LightningElement, api } from 'lwc';
import { addItemToCart } from 'commerce/cartApi';

export default class AddToCartButton extends LightningElement {
    @api productId;
    @api quantity = 1;

    async handleAddToCart() {
        try {
            await addItemToCart({ productId: this.productId, quantity: this.quantity });
            this.dispatchEvent(new CustomEvent('cartupdate'));
        } catch (e) {
            // surface error to buyer UI
            console.error('Add to cart failed', e);
        }
    }
}
```

`addItemToCart` is an imperative function, not a wire adapter. It returns a Promise and must be called inside a user-interaction handler. Do not call it during `connectedCallback` or a wire handler — cart mutations triggered outside user gestures may be blocked by the storefront security context.

---

## Decision Guidance

| Situation | Recommended Approach | Reason |
|---|---|---|
| Reading product data for display | `@wire(getProduct, ...)` from `commerce/productApi` | Declarative binding; store context auto-injected |
| Reading negotiated price for a buyer | `@wire(getProductPrice, ...)` from `commerce/productApi` | Price depends on buyer account; standard LDS has no price concept |
| Adding or removing cart items | Imperative `addItemToCart` / `removeItemFromCart` from `commerce/cartApi` | Mutations must be user-triggered; wire is read-only |
| Displaying wishlist state | `@wire(getWishlist, ...)` from `commerce/wishlistApi` | Wishlist is buyer-scoped; standard LDS cannot resolve it |
| Component not showing in Experience Builder | Verify `isExposed: true` and correct `<targets>` in `.js-meta.xml` | Registration issue, not a code issue |
| Component rendering inconsistently in live store | Add `lightningCommunity__RelaxedCSP` capability to meta XML | LWR disables Locker; capability must be explicit |

---

## Recommended Workflow

Step-by-step instructions for an AI agent or practitioner working on this task:

1. **Confirm store type and target page.** Identify whether the store is B2B Commerce or D2C, and which page type the component will be placed on (product detail page, cart page, checkout step, etc.). This determines which `commerce/*` adapters are available and which Experience Builder page targets to register.
2. **Select the correct Commerce wire adapters.** Import from `commerce/productApi`, `commerce/cartApi`, or `commerce/wishlistApi` as appropriate. Do not use `lightning/uiRecordApi` or `lightning/uiObjectInfoApi` — these modules are unavailable in the LWR storefront runtime.
3. **Scaffold the LWC bundle.** Create the `.html`, `.js`, and `.js-meta.xml` files. In the JS, wire or import from the correct `commerce/*` module. Expose reactive getters for template binding rather than accessing `.data` directly in the template.
4. **Configure the meta XML correctly.** Set `isExposed: true`, add `lightningCommunity__RelaxedCSP` to `<capabilities>`, and add the correct `<targets>` entry. Expose design-time properties via `<targetConfigs>` if store admins need to configure the component.
5. **Deploy via SFDX.** Run `sfdx force:source:push` or `sf project deploy start` targeting the store org. Verify the component appears in Experience Builder under Custom Components.
6. **Test in Experience Builder preview and live store.** CSP and adapter behavior can differ between Builder preview mode and live store rendering. Always test in both contexts before release.
7. **Validate and review.** Run `python3 scripts/check_commerce_lwc_components.py --manifest-dir force-app/main/default/lwc/` to catch missing CSP declarations and incorrect adapter imports.

---

## Review Checklist

Run through these before marking work in this area complete:

- [ ] All wire adapters imported from `commerce/*` modules, not `lightning/uiRecordApi` or `lightning/uiObjectInfoApi`
- [ ] `.js-meta.xml` includes `<capability>lightningCommunity__RelaxedCSP</capability>`
- [ ] `.js-meta.xml` has `isExposed: true` and at least one valid `<target>` entry
- [ ] Cart and wishlist mutations are imperative function calls inside user-interaction handlers, not wire reactive properties
- [ ] Component tested in both Experience Builder preview and live store page
- [ ] No hardcoded store IDs, buyer group IDs, or catalog IDs — context is injected by the LWR runtime

---

## Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

1. **Missing `lightningCommunity__RelaxedCSP` causes silent rendering failures** — A component that previews correctly in Experience Builder may fail to render on certain live store page types (especially checkout and cart pages) if the `lightningCommunity__RelaxedCSP` capability is absent. The error is not surfaced to the buyer; the component simply does not appear. Always declare this capability even if the component does not use any CSP-restricted APIs directly.
2. **`getProduct` fields list is not free-form** — The `fields` parameter for `getProduct` must use field names in the exact format expected by the Commerce Product API, not the same format as `lightning/uiRecordApi`. For example, `Name` works but `Product2.Name` does not. Passing unsupported field names silently returns `undefined` for those fields rather than throwing an error.
3. **LDS is unavailable; `@wire(getRecord)` returns no data and no error** — In the LWR storefront runtime, `lightning/uiRecordApi` adapters are not loaded. A wire adapter imported from `lightning/uiRecordApi` will resolve its import successfully at compile time but never deliver data at runtime, producing no JavaScript error. This means a developer testing in App Builder will see data but a buyer in the store will see a blank component.

---

## Output Artifacts

| Artifact | Description |
|---|---|
| `<componentName>.js` | LWC controller with `commerce/*` wire adapter imports and reactive getters |
| `<componentName>.html` | Template referencing reactive getter properties, not raw `.data` access |
| `<componentName>.js-meta.xml` | Meta XML with `lightningCommunity__RelaxedCSP`, `isExposed: true`, and correct `<targets>` |
| Deployment confirmation | Output of `sf project deploy start` confirming component is registered in the store org |

---

## Related Skills

- `lwc/wire-service-patterns` — use for standard LWC wire service patterns outside the Commerce storefront context
- `admin/b2c-commerce-store-setup` — use when setting up the B2C store configuration before building custom components
- `integration/commerce-order-api` — use when a custom component must trigger order placement or order management operations beyond cart mutations
</content>
</invoke>

Related Skills

lwc-web-components-interop

8
from PranavNagrecha/AwesomeSalesforceSkills

LWC interop with non-LWC web components: consuming third-party standard custom elements in LWC, exposing LWC as custom elements externally, Shadow DOM vs native web components, polyfills, and slotting patterns. NOT for LWC-to-LWC composition (use lwc-best-practices). NOT for Aura interop (use aura-to-lwc-migration).

lwc-dynamic-components

8
from PranavNagrecha/AwesomeSalesforceSkills

Dynamic LWC component creation using the `lwc:component` directive, lazy-loaded dynamic imports (`import()`), and runtime component resolution for conditional rendering at scale. Triggers: 'render different components based on record type', 'dynamically load lwc at runtime', 'lwc:component lwc:is constructor', 'lazy load component only when needed', 'dynamic import lwc'. NOT for static component composition or `lwc:if` conditional rendering when the component set is fixed at build time (use lwc-conditional-rendering).

experience-cloud-lwc-components

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building custom LWC components for Experience Cloud (Experience Builder sites, LWR portals, Aura-based communities). Covers community context imports, guest user Apex access patterns, navigation API differences between LWR and Aura, and JS-meta.xml target configuration for Experience Builder exposure. NOT for internal LWC components deployed to Lightning App Builder or standard record pages (see lwc/lwc-development). NOT for Aura community components. Trigger keywords: build LWC for Experience Cloud, custom component community portal LWC, guest user LWC component, community context import salesforce, lightningCommunity target, @salesforce/community, guest Apex.

flow-screen-lwc-components

8
from PranavNagrecha/AwesomeSalesforceSkills

Design custom Lightning Web Components that render inside Screen Flow steps — covers the lightning__FlowScreen target, @api properties as Flow inputs/outputs, FlowAttributeChangeEvent propagation, FlowNavigationNext/Back/Finish/Pause events, the @api validate() hook, and design-time targetConfig wiring. NOT for custom property editors that configure flow elements at design time — see flow-custom-property-editors. NOT for the LWC implementation deep-dive — see lwc/lwc-in-flow-screens.

flow-reactive-screen-components

8
from PranavNagrecha/AwesomeSalesforceSkills

Build reactive Flow screens where one component updates another without navigation using reactive formulas and component outputs. NOT for Aura-based screens.

product-catalog-migration-commerce

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when migrating product catalog data into Salesforce B2B Commerce — covers category hierarchy, product attributes, images, pricing, and variant structure using the Commerce Import API. NOT for CPQ product catalog migration, post-migration catalog configuration, or commerce catalog taxonomy planning.

commerce-order-history-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when migrating historical order records into Salesforce Order Management — covers the required object creation sequence (Order > OrderDeliveryGroup > OrderItem > OrderSummary), LifeCycleType=Unmanaged for historical orders, and OrderSummary creation via ConnectAPI. NOT for standard Opportunity migration, CPQ legacy order migration using SBQQ objects, or active order processing.

commerce-inventory-data

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when managing inventory data in Salesforce Omnichannel Inventory (OCI) — covers stock level APIs, warehouse location mapping, IMPEX bulk upload, inventory availability queries, reservation management, and reorder point design. NOT for Field Service Lightning inventory management, Salesforce standard Product object stock fields, or CPQ product configuration.

commerce-analytics-data

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when analyzing B2C Commerce storefront metrics (conversion funnel, cart abandonment, product performance, revenue trends) via the Business Manager Reports and Dashboards app, or when deriving B2B Commerce analytics via SOQL on core platform objects or the CRM Analytics B2B Commerce template. NOT for CRM Analytics platform configuration, Einstein Analytics, Experience Cloud analytics, or general Salesforce report builder usage.

headless-commerce-architecture

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when designing or evaluating a headless B2C Commerce storefront architecture — covering the Composable Storefront (PWA Kit on Managed Runtime), SCAPI-first API design, frontend framework selection, latency budgets, and caching strategy. NOT for standard SFRA storefronts, Experience Cloud headless CMS delivery, B2B Commerce architecture, or SCAPI implementation-level coding (use apex/headless-commerce-api for that).

composable-commerce-architecture

8
from PranavNagrecha/AwesomeSalesforceSkills

Composable commerce on Salesforce: headless API layer, micro-frontends, BFF pattern, CDN strategy, third-party composability over B2C/B2B Commerce. NOT for the standard B2C Storefront UX (use b2c-commerce-storefront-setup). NOT for Salesforce Order Management basics (use salesforce-order-management-setup).

commerce-integration-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when designing or diagnosing end-to-end integration between Salesforce B2B or D2C Commerce and external systems — including ERP pricing/inventory, PIM product sync, payment gateways, shipping providers, tax engines, and order management systems (OMS). Covers CartExtension Apex namespace (PricingCartCalculator, ShippingCartCalculator, InventoryCartCalculator), RegisteredExternalService custom metadata, payment gateway architecture, and Product2 External ID patterns. NOT for generic Salesforce integration (platform events, Mulesoft, REST APIs unrelated to commerce), NOT for CommercePayments adapter implementation details (see apex/commerce-payment-integration), NOT for storefront UI or LWC development.