useProductOfferLayout
Use this hook to get the layout for a product offer and turn it into a ready-to-render tree. It is the bridge between the flat list of layout entities assigned to a product and the nested LayoutNode[] structure your UI iterates over.
Getting the controller
import { useProductOfferLayout } from "@expivi/product-configurator";
// main product
const controller = useProductOfferLayout(configurator);
// a specific product
const productController = useProductOfferLayout(configurator, productCid);
When productCid is omitted, the controller targets the main product offer.
Example
import { useProductOfferLayout } from "@expivi/product-configurator";
const controller = useProductOfferLayout(configurator);
// build the nested tree to render
const tree = controller.buildLayout();
tree.forEach(node => {
console.log(node.layoutEntityController?.data.rtti, node.children?.length ?? 0);
});
// rebuild when the product's layout list changes
const unsubscribe = controller.subscribe(() => {
render(controller.buildLayout());
});
// later, when the component unmounts
unsubscribe();
API
data
Returns the raw array of layout entity cids assigned to the selected product (its layoutEntities).
subscribe(callback)
Subscribes to changes of the product's layoutEntities list. Throws if the product offer cannot be found. Returns an unsubscribe function to call during cleanup.
buildLayout()
Builds and returns a nested LayoutNode[] tree suitable for rendering. Each LayoutNode carries a layoutEntityController (or attributeController), plus optional children and parent links.
Behavior:
- When the product has assigned layout entities, they are turned into a nested tree, sorted by position, with invisible nodes filtered out.
StaticGroupedAttributesnodes are expanded into their attribute children via a grouped-attributes builder chosen from the main product'sgroupedProductAttributessetting:bundle_level,option_level, ornone(product level).- When no layout is configured, a default layout is built from the main product's attributes, followed by grouped sub-products (using the same builder selection) when sub-products exist.