Use when configuring or troubleshooting the B2B/B2C Commerce product catalog — ProductCatalog, ProductCategory, ProductCategoryProduct, WebStoreCatalog, CommerceEntitlementPolicy, product attributes, and product variants. Trigger keywords: product catalog, product category, commerce catalog, entitlement policy, product variants, product attributes, catalog visibility. NOT for CPQ product catalog (bundles, options, price rules) or for loading standard Product2/Pricebook2 data outside Commerce.
This skill activates when a practitioner needs to create, configure, or troubleshoot the B2B or B2C Commerce product catalog — including category hierarchy setup, product assignment to categories, entitlement policy configuration for buyer visibility, and product attribute/variant modeling. It does not cover CPQ catalog configuration or standard Product2/Pricebook2 data loading outside of a Commerce context.
Gather this context before working on anything in this domain:
ProductCatalog is the top-level container for a Commerce catalog. Each store is linked to exactly one ProductCatalog through a WebStoreCatalog junction record. A single ProductCatalog can serve multiple stores, but a store may not reference multiple catalogs simultaneously. Attempting to create a second WebStoreCatalog for the same store results in a validation error.
ProductCategory records form the navigational and organizational hierarchy within a catalog. Categories are linked to their catalog via the CatalogId field on ProductCategory. Categories can be nested (parent–child) to arbitrary depth, though very deep hierarchies increase page-load time and are an operational anti-pattern.
Products are assigned to categories through ProductCategoryProduct junction records — one per Product2-per-category assignment. A product can belong to multiple categories within the same catalog.
CommerceEntitlementPolicy records control which products a buyer group can see and purchase. A policy is linked to a BuyerGroup through CommerceEntitlementPolicyGroup. Products are explicitly included in a policy via CommerceEntitlementProduct records.
The platform limit that causes the most production incidents: a single product can be included in at most 2,000 buyer groups for search index purposes. If a product is assigned to more than 2,000 buyer groups (via entitlement policies), Salesforce silently excludes it from search results for those buyer groups beyond the cap. There is no error message. The product still appears via direct URL or catalog browsing, but search will not surface it.
Product variants in Commerce are modeled using ProductAttributeSet (the set of attributes, e.g., Color, Size) and ProductAttribute (individual attribute definitions). A parent product (Product2 with IsActive = true) holds the attribute set reference. Child variant products are separate Product2 records linked to the parent via the VariantParentId field. Each child represents a specific combination of attribute values (e.g., Blue + Large).
Attribute sets must be created and assigned to the parent product before child variants can be created. Attempting to create a variant product without a configured attribute set results in a validation error. Attribute values are stored on ProductAttributeSetProduct junction records.
The Commerce search index is a separate, asynchronous data store derived from the catalog. It must be explicitly rebuilt — via Setup > B2B Commerce > [Store] > Search Index — after any of the following:
Until the index rebuild completes, buyer-facing search results will reflect the previous state.
When to use: Stores with fewer than 200 SKUs and a single buyer segment where all buyers see the same products.
How it works:
ProductCatalog record.ProductCategory records directly under the catalog (no nesting) or with one level of nesting.ProductCategoryProduct for each Product2 → Category assignment.WebStoreCatalog linking the catalog to the store.CommerceEntitlementPolicy and one BuyerGroup; link all products to the policy.Why not the alternative: Nesting categories deeply (3+ levels) for small catalogs adds configuration overhead and slows storefront category navigation without benefit.
When to use: Multiple buyer tiers (e.g., Gold, Silver, Public) need different product visibility within the same store and catalog structure.
How it works:
ProductCatalog and assign it to the store via WebStoreCatalog.ProductCategory records shared across all buyer tiers.BuyerGroup and CommerceEntitlementPolicy per tier.CommerceEntitlementProduct records.Why not the alternative: Separate catalogs per buyer tier requires separate stores (one catalog per store) and multiplies administrative overhead. Segmented entitlement within one catalog is the canonical Commerce approach.
When to use: Products that come in multiple configurations (e.g., clothing in multiple sizes and colors, equipment in multiple voltages).
How it works:
ProductAttributeSet record (e.g., "Apparel Attributes").ProductAttribute records linked to the set (e.g., Color, Size).Product2 record and link the attribute set.Product2 variant records — one per attribute combination — with VariantParentId pointing to the parent.ProductAttributeSetProduct.ProductCategoryProduct; children are discoverable via the parent on the PDP.CommerceEntitlementProduct records as needed.Why not the alternative: Creating separate, unrelated Product2 records for each variant breaks the storefront PDP variant selector and prevents buyers from switching between variants on the same page.
| Situation | Recommended Approach | Reason |
|---|---|---|
| All buyers see the same products | Single BuyerGroup + Single EntitlementPolicy | Simplest setup; fewest records; easiest to maintain |
| Multiple buyer tiers, different product visibility | Multiple BuyerGroups + multiple EntitlementPolicies | Native Commerce entitlement model; stays within one catalog and one store |
| Need separate pricing AND separate product catalogs | Separate stores with separate catalogs | One catalog per store is a platform constraint; pricing differences alone don't require separate catalogs |
| Products in multiple configurations | Variant Products with ProductAttributeSet | Provides storefront variant selector UX; keeps SKU navigation coherent |
| Product visible in admin but missing from buyer search | Rebuild search index; verify entitlement; check 2,000 group cap | Search index is async; entitlement is separate from category assignment |
| Need to move product from one catalog to another | Delete ProductCategoryProduct in old catalog; create new in new catalog; check entitlement policy | Products themselves (Product2) are org-wide; catalog membership is controlled by junction records |
Step-by-step instructions for an AI agent or practitioner working on this task:
WebStoreCatalog for the store's WebStoreId to confirm the active ProductCatalogId. Note: only one record is allowed per store.ProductCategory records with CatalogId pointing to the active catalog.ProductCategoryProduct junction records for each Product2 → ProductCategory pairing. A product can belong to multiple categories.CommerceEntitlementPolicy linked to the appropriate BuyerGroup via CommerceEntitlementPolicyGroup. Create CommerceEntitlementProduct records for each product the segment should see. Verify total buyer group assignments per product remain under 2,000.ProductAttributeSet and ProductAttribute records are in place before creating child variant Product2 records. Set VariantParentId on each child.Run through these before marking work in this area complete:
WebStoreCatalog has exactly one record for the target store with the correct ProductCatalogIdProductCategory records have a valid CatalogId and correct ParentCategoryId hierarchyProductCategoryProduct records exist for all products that should appear in at least one categoryCommerceEntitlementPolicy linked via CommerceEntitlementPolicyGroupCommerceEntitlementProduct records exist for every product the buyer group should seeVariantParentId set and all child variants are linked to the parent's attribute setNon-obvious platform behaviors that cause real production problems:
WebStore record can have exactly one active WebStoreCatalog junction. Attempting to insert a second WebStoreCatalog for the same store raises a validation rule error. To switch catalogs, delete the existing WebStoreCatalog first, then create the new one.CommerceEntitlementPolicy records (and thus more than 2,000 buyer groups), it is silently excluded from search index results for buyer groups beyond the 2,000 limit. No error, no warning, no Apex trigger fires. The product still appears via direct navigation but buyers cannot discover it via search.ProductCategory makes it organizationally visible in the Commerce admin but does not make it visible to buyers. Buyer visibility requires a CommerceEntitlementProduct record in the buyer group's active entitlement policy AND an up-to-date search index.Product2 record cannot be saved without an existing, valid ProductAttributeSet linked to the parent product. Creating variants before the attribute set is configured results in a validation error that does not always provide a clear field-level message in the UI.| Artifact | Description |
|---|---|
| ProductCatalog record | Top-level catalog container associated to the store via WebStoreCatalog |
| ProductCategory records | Hierarchical category structure within the catalog |
| ProductCategoryProduct records | Junction records assigning Product2 to categories |
| WebStoreCatalog record | Junction linking one ProductCatalog to one WebStore |
| CommerceEntitlementPolicy records | Controls which products each buyer group can see and buy |
| CommerceEntitlementProduct records | Junction records listing products visible under a given policy |
| Search Index rebuild confirmation | Setup record showing successful completion of search index rebuild |
| Variant configuration | ProductAttributeSet, ProductAttribute, and child Product2 records with VariantParentId set |