Product Configurator Development on Vue.js for 1C-Bitrix
A product configurator is an interactive tool where the user assembles a product from options (color, size, configuration, extras), while the price, image, and availability update in real time. Bitrix provides trade offer data; Vue provides the reactive interface.
Trade Offers (SKU) in Bitrix
The configurator works with trade offers — a subtype of b_iblock_element linked to the parent product via b_iblock_element_property (a property of type "element link" or via CIBlockElement::GetList with PROPERTY_CML2_LINK).
Data structure for the configurator:
// Get all SKUs with their properties
$offers = \CCatalogSKU::GetOffersList(
[$productId],
$offerIblockId,
['ACTIVE' => 'Y'],
['ID', 'PROPERTY_COLOR', 'PROPERTY_SIZE', 'CATALOG_PRICE_1', 'CATALOG_QUANTITY']
);
Passed to Vue as window.__PRODUCT_CONFIG__:
{
offers: [
{ id: 101, props: { color: 'red', size: 'M' }, price: 1500, quantity: 5 },
{ id: 102, props: { color: 'red', size: 'L' }, price: 1500, quantity: 0 },
// ...
],
propertyDefs: {
color: { name: 'Color', values: { red: { name: 'Red', hex: '#FF0000' } } },
size: { name: 'Size', values: { M: { name: 'M' }, L: { name: 'L' } } },
}
}
SKU Selection Logic
The core of the configurator is a function that finds the matching SKU based on selected parameters:
const selectedProps = reactive({ color: null, size: null });
const matchedOffer = computed(() => {
return offers.find(offer =>
Object.entries(selectedProps).every(([key, val]) =>
val === null || offer.props[key] === val
)
) ?? null;
});
// Available values considering already selected parameters
function getAvailableValues(propKey) {
return offers
.filter(offer =>
Object.entries(selectedProps)
.filter(([k]) => k !== propKey)
.every(([k, v]) => v === null || offer.props[k] === v)
)
.map(offer => offer.props[propKey]);
}
Unavailable combinations (out of stock) are greyed out but not hidden — the user can still see that the option exists.
Dynamic Image Updates
When a color or material is selected, the main product image changes. Images are linked to SKUs in b_iblock_element_property (a property of type "file"):
const currentImages = computed(() => {
if (matchedOffer.value) {
return matchedOffer.value.images; // From the offer data
}
return defaultImages; // Base product images
});
Transitions between images use Vue's <transition> or a simple CSS animation.
Configurator with Dependent Parameters
A more complex case: selecting a model → available configurations → available options. Each level filters the next. Implemented via computed with cascading filtering of offers.
For complex configurators (PC builds, custom furniture) — a hierarchical selection tree with steps (wizard), where each step fetches valid options for the next step via AJAX.
Real-World Case
A window manufacturer: a configurator with 6 parameters (profile type, glazing unit, color, opening type, size, additional options). The number of SKUs was several thousand. All data was loaded when the page opened (800 KB JSON). Solution: lazy loading — at each wizard step, the server is queried for the valid values of the next parameter with current prices. The size of the initial request dropped to 15 KB. Configurator load speed improved significantly.
Delivery Timelines
| Option | Timeline |
|---|---|
| Basic configurator (color, size) | 4 to 7 business days |
| With dependent parameters and dynamic images | 8 to 12 business days |
| Complex wizard with real-time price calculation | 15 to 25 business days |







