Configurator Core Events

Why Type-Safe Events?

Standard JavaScript event subscriptions use string names. A misspelled event name won't produce any error -- the browser simply never fires a callback for a name that doesn't exist, and there is no way to know.

The Epigraph Configurator solves this by storing all event names in an EVENTS object on the Core API. If you try to access an event that doesn't exist, you get a TypeError immediately instead of a silent failure.

// Fragile -- a typo here fails silently
configurator.addEventListener("contxtMenu:show", callback);

// Type-safe -- a typo here throws a TypeError
configurator.addEventListener(coreApi.EVENTS.UI.ContxtMenu_Show, callback);
// → TypeError: Cannot read properties of undefined

Accessing Events

All events are accessed via coreApi.EVENTS.<category>.<eventName>:

const configurator = document.getElementById("wcEpigraphConfigurator");

configurator.addEventListener("coreApi:ready", () => {
  const coreApi = configurator.api.core;

  configurator.addEventListener(
    coreApi.EVENTS.SCENE.Item_Added,
    () => {
      console.log("An item was added to the scene");
    }
  );
});

Note: The coreApi:ready and coreApi:failed lifecycle events are not part of the EVENTS object. These two events must always be subscribed to using string names, since the Core API (and therefore the EVENTS object) is not yet available when you need to listen for them.


Lifecycle Events

These events are subscribed to directly with string names on the web component element:

EventDescription
coreApi:readyThe Core API has initialized and is ready for use
coreApi:failedThe Core API failed to initialize (network error, invalid key, unsupported hardware)
configurator.addEventListener("coreApi:ready", () => {
  // Core API is available at configurator.api.core
});

configurator.addEventListener("coreApi:failed", (event) => {
  // Show error UI to the user
});

UI Events

Events related to the configurator's user interface elements. Access via coreApi.EVENTS.UI.*.

AccessorInternal ValueDescription
PreloadScreen_Showpreload:showThe loading screen should be shown
PreloadScreen_Hidepreload:hideThe loading screen should be hidden
ContextMenu_ShowcontextMenu:showAn item was clicked in the scene; show the context menu
ContextMenu_HidecontextMenu:hideThe context menu should be dismissed
ContextMenu_InfoBtnClickedinfoButtonClicked_ContextMenuThe info button inside the context menu was clicked
UtilityMenu_ShowutilityMenu:showThe utility menu should be shown
UtilityMenu_HideutilityMenu:hideThe utility menu should be hidden
ShareButton_ShowshareButton:showThe share button should be shown
ShareButton_HideshareButton:hideThe share button should be hidden
ViewInYourSpaceButton_ShowviewInYourSpace:showThe AR / View In Your Space button should be shown
ViewInYourSpaceButton_HideviewInYourSpace:hideThe AR button should be hidden
ResetButton_ShowresetBtn:showThe reset button should be shown
ResetButton_HideresetBtn:hideThe reset button should be hidden
DimensionsButton_ShowdimensionsBtn:showThe dimensions button should be shown
DimensionsButton_HidedimensionsBtn:hideThe dimensions button should be hidden
Instructions_Showinstructions:showThe instructions modal should be shown
ReviewCart_Shownreview-cart-shownThe review cart panel was shown
ReviewCart_Hiddenreview-cart-hiddenThe review cart panel was hidden

Example: Custom Context Menu

configurator.addEventListener(
  coreApi.EVENTS.UI.ContextMenu_Show,
  (event) => {
    const item = event.data.primary;
    console.log(`Clicked: ${item.name} (${item.guid})`);
    console.log("Available looks:", item.data.itemData.looks);
    // Show your custom context menu
  }
);

configurator.addEventListener(
  coreApi.EVENTS.UI.ContextMenu_Hide,
  () => {
    // Hide your custom context menu
  }
);

Scene Events

Events related to changes in the 3D scene. Access via coreApi.EVENTS.SCENE.*.

AccessorInternal ValueDescription
Item_Addeditem:addedAn item was added to the scene
Item_Removeditem:removedAn item was removed from the scene
Items_Updateditems:updatedItem data was updated (e.g. position, attachments)
FittingSkuIds_UpdatedfittingSkuIds:updatedThe list of compatible SKU IDs was recalculated
CartItems_UpdatedcartItems:updatedCart contents changed
Hotspot_Enterhotspot:enterThe user entered/activated a hotspot
Hotspot_Exithotspot:exitThe user exited a hotspot
SavedConfiguration_Loadedloaded-saved-configurationA saved configuration was loaded into the scene
MaterialOverrides_ExistsmaterialOverrideExistsA material override was applied to an item
Cart_Checkoutcart:checkoutCheckout was initiated
Cart_OutOfStockcart:outOfStockCheckout was blocked due to out-of-stock items
Cart_StatusUpdatedcart:statusUpdatedCart status was updated
ReplaceableCategory_UpdatedreplaceableCategory:updatedA replaceable item category was changed
GlobalVariant_UpdatedglobalVariant:updatedA global material variant was switched
CategoryData_UpdatedcategoryData:updatedCategory data was updated
GlobalGeometryVariant_UpdatedglobalGeometryVariant:updatedA global geometry variant was switched
Ghost_Loadedghost:loadedGhost previews finished loading
Model_Loadedmodel:loadedA 3D model finished loading
Model_Removedmodel:removedA 3D model was removed
Scene_Clearedscene:clearedThe scene was cleared
Inventory_Updatedinventory:updatedInventory data was updated
DraggingOnDrop_CollisionDetecteddraggingOnDrop:collisionDetectedA collision was detected during drag-and-drop
ItemRemoveModalTriggereditemRemoveModal:triggeredItem removal confirmation was requested
ActionButton_ClickedactionButton:clickedAn action button was clicked
CartMessage_UpdatecartMessage:updatedCart message was updated

Example: Reacting to Scene Changes

configurator.addEventListener(
  coreApi.EVENTS.SCENE.Item_Added,
  () => {
    console.log("Item count:", coreApi.getSceneItemCount());
  }
);

configurator.addEventListener(
  coreApi.EVENTS.SCENE.CartItems_Updated,
  async () => {
    const cartItems = await coreApi.getCartItemsAsync();
    // Update your cart UI
  }
);

configurator.addEventListener(
  coreApi.EVENTS.SCENE.SavedConfiguration_Loaded,
  () => {
    console.log("Configuration loaded successfully");
  }
);

Configuration Events

Events related to item interaction and camera state. Access via coreApi.EVENTS.CONFIGURATION.*.

AccessorInternal ValueDescription
OnClickItemonClickItemAn item was clicked in the scene
CameraDetails_UpdatecameraDetails:UpdateCamera details were updated

Quick Reference

All events at a glance:

EVENTS
├── UI
│   ├── PreloadScreen_Show
│   ├── PreloadScreen_Hide
│   ├── ContextMenu_Show
│   ├── ContextMenu_Hide
│   ├── ContextMenu_InfoBtnClicked
│   ├── UtilityMenu_Show
│   ├── UtilityMenu_Hide
│   ├── ShareButton_Show
│   ├── ShareButton_Hide
│   ├── ViewInYourSpaceButton_Show
│   ├── ViewInYourSpaceButton_Hide
│   ├── ResetButton_Show
│   ├── ResetButton_Hide
│   ├── DimensionsButton_Show
│   ├── DimensionsButton_Hide
│   ├── Instructions_Show
│   ├── ReviewCart_Shown
│   └── ReviewCart_Hidden
├── SCENE
│   ├── Item_Added
│   ├── Item_Removed
│   ├── Items_Updated
│   ├── FittingSkuIds_Updated
│   ├── CartItems_Updated
│   ├── Hotspot_Enter
│   ├── Hotspot_Exit
│   ├── SavedConfiguration_Loaded
│   ├── MaterialOverrides_Exists
│   ├── Cart_Checkout
│   ├── Cart_OutOfStock
│   ├── Cart_StatusUpdated
│   ├── ReplaceableCategory_Updated
│   ├── GlobalVariant_Updated
│   ├── CategoryData_Updated
│   ├── GlobalGeometryVariant_Updated
│   ├── Ghost_Loaded
│   ├── Model_Loaded
│   ├── Model_Removed
│   ├── Scene_Cleared
│   ├── Inventory_Updated
│   ├── DraggingOnDrop_CollisionDetected
│   ├── ItemRemoveModalTriggered
│   ├── ActionButton_Clicked
│   └── CartMessage_Update
└── CONFIGURATION
    ├── OnClickItem
    └── CameraDetails_Update

Preload Events

These string-based events track asset loading progress. They are useful if you want to build a custom loading indicator.

EventDescription
preload:beginAsset preloading has started
preload:updatePreloading progress update -- carries a progress property (0--100)
preload:endAsset preloading is complete
configurator.addEventListener("preload:update", (event) => {
  console.log(`Loading: ${event.progress}%`);
});

Further Reading