Create a custom product detail component by product type

Prev Next

This article is for Experience Builder implementers and developers who need a product detail experience that changes by web product type. Use this pattern when a product type needs its own layout, selection flow, or pricing interactions and the standard product detail components are not enough.

Use this component pattern when you need:

  • a different product detail layout for one web product record type
  • custom option selection before repricing or add-to-cart
  • a record-type-specific buying experience for a custom product model
  • product detail behavior that cannot be achieved through standard component configuration alone

If you only need to reorganize standard description, features, or specifications content, use the product detail accordion instead of building a custom product detail component.

What this component pattern does

OrderCentral can load a custom Lightning Web Component inside the storefront product detail experience based on the current web product record type.

This is not a standalone Experience Builder component that you drag onto the page. Instead, the storefront product detail flow resolves the custom component at runtime by using:

  • the plugin type ProductDetailUIPlugin
  • the current web product RecordType.DeveloperName

When a matching plugin registration is found, OrderCentral loads the configured component bundle and passes product data into it.

The lookup only succeeds when both values are present and the registration matches the record type developer name exactly. A blank record type does not act as a fallback for this extension.

Where this component is used

Use this pattern on storefront product detail pages that already use the standard OrderCentral product detail flow.

The custom component renders inside the product detail area for matching products. That makes it a good fit for record-type-specific product presentation without requiring separate product detail pages for each product type.

Before you begin

Confirm the following before you implement a custom product detail component:

  • the storefront already has a working product detail page
  • the target web product type has a stable Salesforce record type developer name
  • your team can build and deploy a custom Lightning Web Component bundle
  • you have confirmed whether the standard add-to-cart behavior is still valid for this product type
  • you have ruled out standard product detail configuration as the simpler option

Configure the component registration

Register the component under the shipped plugin type ProductDetailUIPlugin.

Create one plugin registration for each web product record type that needs its own custom product detail component.

Custom product detail UI resolution uses two metadata layers:

  • Plugin__mdt identifies the plugin family through Type__c = ProductDetailUIPlugin
  • Plugin_Registration__mdt maps a specific record type to the LWC bundle that should be loaded

The registration record is what selects the custom component bundle for the product type.

Registration checklist

  1. Confirm that a Plugin__mdt record exists for ProductDetailUIPlugin.
  2. Create or update a related Plugin_Registration__mdt record.
  3. Set Record_Type_Name__c to the exact web product record type developer name.
  4. Set Component_Bundle_Name__c to the full LWC bundle reference, such as c/industrialUnitProductDetail.
  5. Deploy the custom LWC bundle to the org.

Registration fields

Metadata field Required value Why it matters
Plugin__mdt.Type__c ProductDetailUIPlugin Identifies the registration as a product detail UI extension.
Plugin_Registration__mdt.Record_Type_Name__c The exact web product RecordType.DeveloperName The component is matched by record type developer name, not by label.
Plugin_Registration__mdt.Component_Bundle_Name__c Full LWC bundle reference such as c/industrialUnitProductDetail Tells OrderCentral which component bundle to load.

Registration example

For a custom web product record type with developer name IndustrialUnit, use values like these:

Setting Example value
Plugin type ProductDetailUIPlugin
Record type name IndustrialUnit
Component bundle name c/industrialUnitProductDetail

The record type name must match exactly. If the registration uses the label instead of the developer name, uses different casing, or is created under the wrong plugin type, the custom component will not load.

Public component contract

OrderCentral passes a simplified product object into the custom component. Build your component around that public contract.

Public property

Property Type Description
product Object Product data provided by OrderCentral for the current product detail page.

Product payload shape

At minimum, the payload includes:

  • product.id: the current web product record ID
  • product.options: a mapped list of web product options when option data is available

The options list is sourced from productData.product.webProductOptions. OrderCentral passes the simplified product object into your component rather than the full upstream product detail payload.

Each option entry includes:

  • id: the option record ID
  • selectOptions.option1: the current option value exposed to the component

Build the component around stable option keys such as selectOptions.option1. Do not depend on display-label-based keys such as translated option labels.

Minimal component shape

import { LightningElement, api } from 'lwc';

export default class IndustrialUnitProductDetail extends LightningElement {
    @api product;

    handleSelectionChange(detail) {
        this.dispatchEvent(
            new CustomEvent('itemchange', {
                detail
            })
        );
    }
}

Events and pricing behavior

When the buyer changes a selection that should affect pricing or ordering state, dispatch an itemchange event from the custom component.

Use a serializable event payload. OrderCentral serializes event.detail and uses it to trigger downstream pricing updates for the product detail experience.

The product detail renderer listens for itemchange and republishes the change through PricingChange__c with:

  • recordId: the current product record ID
  • fields.detailJson: a JSON string version of the itemchange event detail

Use this event when the component changes product option or configuration state that should update price, availability, or related ordering behavior.

The custom component should raise itemchange and let the standard renderer bridge that change into the pricing flow. Avoid bypassing that bridge unless you also control every downstream listener.

Component behavior and limitations

Keep these behaviors in mind when designing the custom component:

  • matching is based on RecordType.DeveloperName, not the record type label
  • one registration applies to one record type only
  • the component bundle name must use the format c/componentName
  • the runtime does not use the plugin metadata developer name to resolve the component
  • a blank record type does not act as a fallback for this UI
  • if no matching registration exists, the custom component is not rendered
  • if the bundle reference is missing or invalid, the custom component cannot load
  • the component should be designed for the full product detail content area rather than a small sidebar or inline slot

If the web product record type developer name changes, update the plugin registration to keep the mapping intact.

If you are upgrading an older custom integration, re-test both the payload shape and the layout. Older components may have assumed a broader upstream product object, label-keyed option data, or a narrower container.

When to add a custom add-to-cart handler

The custom product detail component controls rendering and buyer interaction. It does not automatically change how cart lines are created.

Use the standard cart behavior when the product can still be added with the normal product, quantity, option, and addon structure.

Add a custom cart handler when the product type needs a different add-to-cart interpretation or custom Apex behavior. In that case:

  • implement the IAddProductToCartHandler Apex interface
  • register the class under the AddProductToCartHandler plugin type for the same record type

This lets OrderCentral resolve a custom product detail component and a matching add-to-cart strategy for the same product type.

Validate the component

After deployment, validate both the registration and storefront behavior.

Registration checks

  • confirm the target web product uses the expected record type developer name
  • confirm Record_Type_Name__c matches that developer name exactly
  • confirm Component_Bundle_Name__c uses the c/componentName format
  • confirm the registration is created under ProductDetailUIPlugin
  • confirm the referenced LWC bundle is deployed and available for runtime import

Storefront checks

  • open a product detail page for a product that uses the target record type
  • confirm the custom component renders in the product detail area
  • confirm the component receives a product object with id and options
  • confirm option data is sourced from productData.product.webProductOptions
  • change at least one option and confirm repricing or state updates occur as expected
  • test both desktop and mobile layouts

Add-to-cart checks

  • test add-to-cart with the standard handler if no custom handler is registered
  • if a custom IAddProductToCartHandler is registered, confirm the resulting cart lines match the intended structure
  • confirm the same record type mapping is used for both the UI registration and the cart handler registration

Test guidance

Add automated tests that confirm:

  • the resolver returns the expected component bundle for the target record type
  • the renderer passes the simplified product payload into the custom component
  • option values are read from productData.product.webProductOptions
  • the custom component dispatches itemchange with JSON-safe detail data

Troubleshooting

If the component does not behave as expected, check these issues first:

  • Record_Type_Name__c does not exactly match the product record type developer name
  • Component_Bundle_Name__c does not use the correct c/componentName reference
  • the registration was created for the wrong plugin type
  • the component still expects the older option payload shape or display-label-based keys
  • the component dispatches non-serializable data in itemchange
  • the product type requires a custom add-to-cart handler but only the UI component was implemented

When to use the standard accordion instead

Use the standard product detail accordion when you only need to reorganize or present standard content such as descriptions, features, and specifications.

Use a custom product detail component when the product type needs its own rendering logic, interaction model, or extension behavior.