Configuration Events
Configuration events fire during the active configuration session for standard products — from the moment a product opens to the moment the user leaves. They cover option selection, price updates, tab and filter changes, history navigation, and 3D scene interactions.
For modular product events, see Modular Events.
Option Selection Flow
The most common integration pattern involves tracking what the user selects. Here's the sequence when a user picks an option:
User selects option in the option panel
│
▼
mimeeq-select-option ← which option, which block, new variant code
│
├── if price-affecting ────► mimeeq-price-change ← about to fetch new price
│ │
│ ▼
│ (price fetched from server)
│ │
│ ▼
│ pricing observer updates
│
└── 3D/2D scene updates in parallel
When a user selects a popular variant instead, the flow is similar but starts with mimeeq-select-popular-variant — and because the entire configuration changes at once, a single mimeeq-price-change follows for the new variant.
Events give you point-in-time notifications — "option X was just selected." Observers give you continuous state — "here is the complete configuration right now." For many integrations, you'll use both: events for analytics and triggering side effects, observers for keeping your UI in sync. See Observers for the full API.
History Flow
Every option change is recorded in a history stack. When the user interacts with the history widget (or you call the history actions programmatically), these events fire:
User clicks Undo User clicks Redo User clicks Reset
│ │ │
▼ ▼ ▼
mimeeq-history-go-back mimeeq-history-go-forward mimeeq-history-reset
│ │ │
└─────────────────────────┴─────────────────────────┘
│
▼
3D/2D scene reverts to that state
pricing observer updates
The history events carry a HistoryItem payload for back/forward, giving you the configuration state at that history point. Reset returns to the initial configuration and carries no payload.
3D Interaction Flow
When meshes in the 3D scene have behaviors assigned (configured in the admin panel), clicking or hovering on them fires events that connect the 3D canvas to the option panel:
Hover over mesh with Highlight Group behavior
│
├── mmq-action-highlight-group-on ← block ID
│
└── (cursor leaves) ──► mmq-action-highlight-group-off
Click mesh with Open Group action
│
└── mmq-action-open-group ← block ID, option panel opens that block
Click mesh with Scroll to Block action
│
├── mmq-action-scroll-to-block ← block ID
│
└── mmq-action-flash-highlight-block ← block ID, fires after scroll completes
These are useful when building a custom option panel — they tell you which block the user is interacting with in 3D space, so you can highlight or scroll your custom UI to match.
Events
mimeeq-enter-product
The standard product configurator has opened. This fires after the embed resolves which product to display and begins rendering it. At this point the product data is available but the 3D/2D scene may still be loading — wait for mimeeq-3d-product-initialized or mimeeq-2d-product-initialized if you need the visual scene ready.
The prefix is the product's short code (the 6-character identifier used in embed snippets and URLs). It stays constant for a product regardless of configuration changes.
Payload: ProductPrefixEventPayload
| Field | Type | Description |
|---|---|---|
prefix | string | Variant code prefix (short code) of the product |
document.addEventListener('mimeeq-enter-product', (event) => {
const { prefix } = event.detail;
// Track which products users actually open
analytics.track('product_configurator_opened', { productCode: prefix });
// Show your custom UI elements that depend on being inside a configurator
document.getElementById('custom-toolbar').style.display = 'block';
});
mimeeq-leave-product
The standard product configurator has been closed or the user navigated away. Use this to tear down any product-specific integration state — custom UI elements, observer subscriptions tied to this product, external system connections.
This fires before mimeeq-embed-unmounted in the teardown flow. The distinction matters: leave-product means "this product session ended" while embed-unmounted means "the entire embed element is gone from the DOM."
Payload: ProductPrefixEventPayload
| Field | Type | Description |
|---|---|---|
prefix | string | Variant code prefix (short code) of the product |
document.addEventListener('mimeeq-leave-product', (event) => {
const { prefix } = event.detail;
// Calculate time spent configuring
const duration = Date.now() - sessionStart;
analytics.track('product_configurator_closed', {
productCode: prefix,
durationMs: duration,
});
// Clean up product-specific state
document.getElementById('custom-toolbar').style.display = 'none';
});
mimeeq-select-option
An option was selected in the option panel. This is the most frequently fired configuration event and the primary hook for tracking what the user is building. It fires for every individual option change — whether the user clicked a thumbnail, picked from a dropdown, typed text, or selected a colour.
The variantCode in the payload is the full variant code after the change, in prefix=configurationCode format. The option object contains the complete option data including its code, name, thumbnail URL, and price-related properties.
Payload: SelectOptionEventPayload
| Field | Type | Description |
|---|---|---|
variantCode | string | Full variant code after the change, in prefix=configurationCode format |
productId | string | Unique identifier of the product being configured |
option | OptionSetOption | The option object that was selected, including code, name, and visual properties |
groupName | string | Display name of the option block (group) the selected option belongs to |
// Track configuration changes for analytics
document.addEventListener('mimeeq-select-option', (event) => {
const { variantCode, groupName, option } = event.detail;
analytics.track('option_selected', {
variantCode,
blockName: groupName,
optionCode: option.code,
optionName: option.name,
});
});
// Sync configurator state with an external inventory system
document.addEventListener('mimeeq-select-option', (event) => {
const { variantCode } = event.detail;
// Extract the configuration code from the variant code
const configCode = variantCode.split('=')[1];
checkInventory(configCode).then((availability) => {
const badge = document.getElementById('stock-badge');
badge.textContent = availability.inStock ? 'In Stock' : `${availability.leadDays} day lead time`;
badge.className = availability.inStock ? 'badge-green' : 'badge-amber';
});
});
If you need the complete configuration state (all selected options across all blocks) rather than just the latest change, use the selectedConfiguration or optionSets.selectedOptions observer instead. The event tells you what just changed; the observer tells you where things stand.
mimeeq-select-popular-variant
A popular configuration variant was selected. Popular variants are curated configurations set up in the admin panel — they represent common or recommended product setups that let users jump to a complete configuration in one click instead of selecting options individually.
When this fires, the entire configuration changes at once. A mimeeq-price-change event follows as the price is recalculated for the new variant.
Payload: SelectPopularVariantEventPayload
| Field | Type | Description |
|---|---|---|
variantCode | string | Full variant code of the selected popular configuration |
productId | string | Unique identifier of the product |
image | string | URL of the preview image for the selected configuration |
// Show the popular variant image in your custom UI while the 3D scene updates
document.addEventListener('mimeeq-select-popular-variant', (event) => {
const { image, variantCode } = event.detail;
const preview = document.getElementById('quick-preview');
preview.src = image;
preview.style.display = 'block';
// Hide preview once the 3D scene catches up
document.addEventListener('mimeeq-3d-product-initialized', () => {
preview.style.display = 'none';
}, { once: true });
});
mimeeq-select-tab
The user switched between tabs in the configurator. Tabs can include the configuration panel, gallery, files, custom content tabs, and any tabs added through the admin panel. The hash identifies the tab type, and index gives its position.
Fires in both standard and modular configurators.
Payload: SelectTabEventPayload
| Field | Type | Description |
|---|---|---|
hash | string | Hash identifier of the selected tab |
index | number | Zero-based index of the selected tab |
// Track which tabs users visit to understand engagement patterns
document.addEventListener('mimeeq-select-tab', (event) => {
const { hash, index } = event.detail;
analytics.track('configurator_tab_switched', { tabHash: hash, tabIndex: index });
});
mimeeq-price-change
A price recalculation is about to be triggered. This fires just before the configurator fetches an updated price from the server — use it to show a loading state on any external price display. The actual updated price arrives through the pricing.prices observer once the server responds.
Fires in both standard and modular configurators. For standard products, the payload includes the variant code and quantity. For modular products, this event fires without a payload.
Payload: PriceChangeEventPayload
| Field | Type | Description |
|---|---|---|
variantCode | string | Current variant code the price will be fetched for |
quantity | number | Current quantity the price will be calculated for |
// Show loading state on external price display during price fetch
document.addEventListener('mimeeq-price-change', (event) => {
if (event.detail) {
const { variantCode, quantity } = event.detail;
const priceEl = document.getElementById('external-price');
priceEl.textContent = 'Updating...';
priceEl.classList.add('loading');
}
});
// Then listen on the observer for the actual price
window.mimeeqApp.observers.pricing.prices.subscribe(({ newValue }) => {
if (newValue) {
const priceEl = document.getElementById('external-price');
priceEl.textContent = `${newValue.currency} ${newValue.price.toFixed(2)}`;
priceEl.classList.remove('loading');
}
});
mimeeq-change-quantity
The user changed the quantity value in the configurator's quantity input. This fires for every quantity adjustment — whether the user clicked the increment/decrement buttons or typed a value directly.
Fires in both standard and modular configurators.
Payload: ChangeQuantityEventPayload
| Field | Type | Description |
|---|---|---|
quantity | number | The new quantity value |
document.addEventListener('mimeeq-change-quantity', (event) => {
const { quantity } = event.detail;
// Update external quantity display or trigger quantity-based logic
document.getElementById('external-qty').textContent = quantity;
analytics.track('quantity_changed', { quantity });
});
mimeeq-select-filters
The user changed filter selections in the configurator's filter panel. Filters narrow down which options are visible — for example, filtering materials by colour family or texture type. The selectedFilters array contains the identifiers of all currently active filters (not just the one that changed).
Fires in both standard and modular configurators.
Payload: SelectFiltersEventPayload
| Field | Type | Description |
|---|---|---|
selectedFilters | string[] | Array of all currently active filter identifiers |
// Track filter usage to understand which filters help users find options
document.addEventListener('mimeeq-select-filters', (event) => {
const { selectedFilters } = event.detail;
analytics.track('filters_changed', {
activeFilters: selectedFilters,
filterCount: selectedFilters.length,
});
});
mimeeq-clear-filters
The "Clear Filters" button was clicked, removing all active filters. After this event, all options become visible again regardless of previous filter selections.
Fires in both standard and modular configurators.
Payload: none
document.addEventListener('mimeeq-clear-filters', () => {
analytics.track('filters_cleared');
});
mimeeq-deactivate-matching-options
The "Match Options" toggle was clicked in the option panel. Match Options is a feature that synchronizes related option selections across blocks — for example, selecting a "walnut" finish in one block automatically selects "walnut" in related blocks. When the user deactivates it, they can select different finishes per block independently.
Fires in both standard and modular configurators. The state reflects the new state after the toggle: true means matching is now active, false means the user turned it off.
Payload: DeactivateMatchingOptionsEventPayload
| Field | Type | Description |
|---|---|---|
groupId | string | Identifier of the option group affected by the matching toggle |
state | boolean | Whether matching is now active (true) or inactive (false) |
mimeeq-activate-matching-options
The "Match Options" toggle was clicked when it was inactive, activating synchronization across related blocks. This is the counterpart to mimeeq-deactivate-matching-options — the payload is identical, with state: true indicating matching is now on.
Fires in both standard and modular configurators.
Payload: DeactivateMatchingOptionsEventPayload
| Field | Type | Description |
|---|---|---|
groupId | string | Identifier of the option group affected by the matching toggle |
state | boolean | Whether matching is now active (true) or inactive (false) |
mimeeq-download-file
A file was downloaded from the configurator's gallery tab or files tab. Gallery and files tabs can contain product images, technical drawings, CAD files, or any documents uploaded through the admin panel. This event fires after the browser initiates the download.
Fires in both standard and modular configurators.
Payload: DownloadFileEventPayload
| Field | Type | Description |
|---|---|---|
fileName | string | Display name of the downloaded file |
href | string | URL the file was downloaded from |
// Track file downloads for content engagement analytics
document.addEventListener('mimeeq-download-file', (event) => {
const { fileName, href } = event.detail;
analytics.track('file_downloaded', {
fileName,
fileType: fileName.split('.').pop(),
source: href,
});
});
mimeeq-open-related-product
A related product link was clicked within the configurator. Related products are configured in the admin panel and displayed within the configurator to cross-sell or upsell. Clicking one navigates the user to a different product — a new mimeeq-enter-product (or mimeeq-modular-enter-product if isModular is true) will fire for the target product.
Fires in both standard and modular configurators.
Payload: OpenRelatedProductEventPayload
| Field | Type | Description |
|---|---|---|
variantCode | string | Variant code of the related product |
productId | string | Unique identifier of the related product |
isModular | boolean | Whether the related product is a modular product |
// Track cross-sell engagement
document.addEventListener('mimeeq-open-related-product', (event) => {
const { variantCode, productId, isModular } = event.detail;
analytics.track('related_product_clicked', {
targetVariant: variantCode,
targetProductId: productId,
targetType: isModular ? 'modular' : 'standard',
});
});
History Events
mimeeq-history-go-back
The user clicked the undo button in the history widget, or mimeeqApp.actions.goBack() was called programmatically. The payload contains the HistoryItem representing the configuration state the user is reverting to.
Payload: HistoryItem
// Sync undo/redo with your custom UI
document.addEventListener('mimeeq-history-go-back', (event) => {
const historyItem = event.detail;
updateBreadcrumb('Reverted to previous configuration');
});
mimeeq-history-go-forward
The user clicked the redo button in the history widget, or mimeeqApp.actions.redo() was called programmatically. The payload contains the HistoryItem representing the configuration state being restored.
Payload: HistoryItem
mimeeq-history-reset
The user clicked the reset button, or mimeeqApp.actions.reset() was called programmatically. This returns the configurator to the initial configuration state — the default options the product was set up with. All history is cleared.
Payload: none
// Confirm reset action in your custom UI
document.addEventListener('mimeeq-history-reset', () => {
showNotification('Configuration reset to defaults');
updateBreadcrumb('Default configuration');
});
mimeeq-configurator-go-back
The back arrow in the configurator was clicked. This navigates to the previous product or view — it is not the same as configuration history undo. Think of it as browser-style navigation within the embed (e.g., going back from a related product to the original one).
Fires in both standard and modular configurators.
Payload: none
mimeeq-configurator-clear-history
The close button was clicked on a configurator running in modal mode. The configurator closes and its configuration history is cleared. This only applies when the embed is displayed as a modal/popup overlay, not when it's inline on the page.
Fires in both standard and modular configurators.
Payload: none
3D Interaction Events
These events fire when the user interacts with meshes in the 3D scene that have special behaviors assigned through the admin panel's rules system. They bridge the gap between the 3D canvas and the option panel — essential when building custom UIs that need to stay in sync with 3D interactions.
mmq-action-highlight-group-on
The user hovered over a mesh that has the Highlight Group behavior assigned. The payload is the block ID of the option block associated with this mesh. Use this to highlight the corresponding block in a custom option panel.
Payload: string — the affected block ID
// Highlight the matching block in your custom option panel
document.addEventListener('mmq-action-highlight-group-on', (event) => {
const blockId = event.detail;
const block = document.querySelector(`[data-block-id="${blockId}"]`);
if (block) {
block.classList.add('highlighted');
}
});
document.addEventListener('mmq-action-highlight-group-off', (event) => {
const blockId = event.detail;
const block = document.querySelector(`[data-block-id="${blockId}"]`);
if (block) {
block.classList.remove('highlighted');
}
});
mmq-action-highlight-group-off
The user moved the cursor away from a mesh with the Highlight Group behavior. Pair this with mmq-action-highlight-group-on to toggle visual highlights in your custom UI.
Payload: string — the affected block ID
mmq-action-open-group
The user clicked a mesh with the Open Group action. This opens the corresponding option block in the standard option panel. If you're using a custom option panel, listen for this event to expand or focus the matching block in your UI.
Payload: string — the affected block ID
// Open the matching accordion section in your custom panel
document.addEventListener('mmq-action-open-group', (event) => {
const blockId = event.detail;
// Close all sections
document.querySelectorAll('.option-section').forEach((s) => s.classList.remove('open'));
// Open the target section
const target = document.querySelector(`.option-section[data-block-id="${blockId}"]`);
if (target) {
target.classList.add('open');
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
mmq-action-scroll-to-block
The user clicked a mesh with the Scroll to Block action. In the standard option panel, this scrolls to the corresponding block and briefly highlights it. The scroll event fires first, then mmq-action-flash-highlight-block fires once the scroll animation completes.
Payload: string — the affected block ID
mmq-action-flash-highlight-block
Fires after the option panel has scrolled to the target block following a Scroll to Block mesh click. The block is briefly highlighted with a flash animation to draw the user's attention. If you're building a custom option panel, use this as the signal to apply your own highlight effect after scrolling completes.
Payload: string — the affected block ID
mimeeq-click-hotspot
The user clicked on a hotspot in the 3D scene. Hotspots are interactive points placed on the 3D model through the admin panel — they can show tooltips, trigger configuration changes through rules, or act as entry points for custom information overlays.
The dimensions give you screen-space pixel coordinates of where the click happened, so you can position a tooltip or popup relative to the hotspot on screen. The meshId identifies which mesh the hotspot is attached to, and instanceId identifies the runtime 3D model instance (relevant when the same model appears multiple times).
Payload: ClickHotspotEventPayload
| Field | Type | Description |
|---|---|---|
meshId | string | Identifier of the mesh the hotspot is attached to |
instanceId | string | Runtime instance identifier of the 3D model |
dimensions | { x: number, y: number } | Screen-space coordinates of the click position (pixels) |
// Position a custom tooltip at the hotspot location
document.addEventListener('mimeeq-click-hotspot', (event) => {
const { meshId, dimensions } = event.detail;
const tooltip = document.getElementById('hotspot-tooltip');
tooltip.style.left = `${dimensions.x}px`;
tooltip.style.top = `${dimensions.y}px`;
tooltip.style.display = 'block';
// Load content specific to this hotspot
fetch(`/api/hotspot-content/${meshId}`)
.then((res) => res.json())
.then((data) => {
tooltip.querySelector('.title').textContent = data.title;
tooltip.querySelector('.description').textContent = data.description;
});
});
// Also listen for the observer to know when the hotspot is no longer active
window.mimeeqApp.observers.product.hotSpot.subscribe(({ newValue }) => {
if (!newValue) {
document.getElementById('hotspot-tooltip').style.display = 'none';
}
});
View Events
mimeeq-3d-open-full-screen
The user entered fullscreen view for the 3D canvas. In fullscreen, the canvas expands to fill the entire viewport. Use this to hide any custom overlays that shouldn't appear in fullscreen, or to adjust the layout of surrounding page elements.
Payload: none
document.addEventListener('mimeeq-3d-open-full-screen', () => {
// Hide custom floating elements that would overlap fullscreen
document.getElementById('custom-price-overlay').style.display = 'none';
document.body.classList.add('mimeeq-fullscreen-active');
});
document.addEventListener('mimeeq-3d-close-full-screen', () => {
document.getElementById('custom-price-overlay').style.display = 'block';
document.body.classList.remove('mimeeq-fullscreen-active');
});
mimeeq-3d-close-full-screen
The user left fullscreen view. The canvas returns to its original size within the embed container.
Payload: none
mimeeq-3d-show-dimensions
The user activated the dimensions overlay by clicking the "Show dimensions" button. Dimension lines showing width, height, and depth are displayed on the 3D scene.
Fires in both standard and modular configurators.
Payload: none
mimeeq-3d-hide-dimensions
The user deactivated the dimensions overlay by clicking the "Show dimensions" button while it was active.
Fires in both standard and modular configurators.
Payload: none
// Track dimension toggle usage
document.addEventListener('mimeeq-3d-show-dimensions', () => {
analytics.track('dimensions_shown');
});
document.addEventListener('mimeeq-3d-hide-dimensions', () => {
analytics.track('dimensions_hidden');
});
mimeeq-3d-zoom-out-scene
The "Zoom Out" button on the 3D canvas toolbar was clicked, resetting the camera to show the full product.
Fires in both standard and modular configurators.
Payload: none
mimeeq-open-option-panel
An option block group (accordion) was opened in the option panel. This fires whenever the user expands a collapsed block group, on both desktop and mobile, in both standard and modular configurators.
Payload: none
URL Events
mimeeq-app-url-change
The current configuration state has changed and the URL should be updated to reflect it. This fires on virtually every user action that changes the configuration: selecting an option, undo/redo/reset, selecting a popular variant, navigating to a related product, and finishing configuration (standard products only — modular does not fire this on finish).
The primary use case is for SPAs or custom embeds that need to keep the browser URL in sync with the configurator state, enabling deep linking and browser back/forward navigation.
The payload shape depends on context. After most configuration actions and finish events, it carries the current FinishEventPayload. When navigating to a related product, it carries a navigation payload with additional routing fields:
| Field | Type | Description |
|---|---|---|
variantCode | string | Current variant code |
productId | string | Current product identifier |
key | string | undefined | Unique key for the navigation action (related product navigation only) |
target | string | undefined | Navigation target hint, e.g., '_blank' (related product navigation only) |
isModular | boolean | undefined | Whether the target product is modular (related product navigation only) |
isPreview | boolean | undefined | Whether the target is in preview mode (related product navigation only) |
Fires for standard products only. Does not fire for modular products.
// Keep the browser URL in sync with the configurator state
document.addEventListener('mimeeq-app-url-change', (event) => {
const { variantCode, productId } = event.detail;
const url = new URL(window.location);
url.searchParams.set('variant', variantCode);
url.searchParams.set('product', productId);
window.history.replaceState({}, '', url);
});
// Handle related product navigation — open in a new tab
document.addEventListener('mimeeq-app-url-change', (event) => {
const { variantCode, target, isModular } = event.detail;
if (target === '_blank') {
const url = new URL(window.location.origin + '/configurator');
url.searchParams.set('variant', variantCode);
if (isModular) {
url.searchParams.set('type', 'modular');
}
window.open(url.toString(), '_blank');
}
});
Related
- Modular Events — events specific to the modular configurator
- Lifecycle Events — when the configurator is ready and when it's removed
- Finish & Cart Events — what happens after the user finishes configuring
- Observers — continuous state tracking via
selectedConfiguration,pricing.prices,optionSets.blocks - Actions — programmatically triggering option changes with
markOptionByBlockNameAndOptionCode - Programmatic Configuration — recipes for headless and guided selling flows