Skip to main content

useVisualization2d

Drives a 2D image-based product visualization. On every settled configuration it re-evaluates the product's published 2D visualization, resolves each returned layer to an image URL, and exposes an ordered, composited layer stack. Reach for it when you want to render a live 2D preview by stacking transparent PNG layers.

Getting the controller

import { useVisualization2d } from "@expivi/product-configurator";

const controller = useVisualization2d(configurator);

The controller subscribes to the product-rules engine and refreshes (debounced) whenever the configuration settles. It only produces data when the main product has a publishedVisualization2dId; otherwise data is null.

Example: rendering a stacked 2D preview

import { useVisualization2d } from "@expivi/product-configurator";

const controller = useVisualization2d(configurator);

const unsubscribeData = controller.subscribe(layers => {
if (!layers) {
clearPreview();
return;
}

// Layers are already sorted by layerIndex (bottom to top).
container.replaceChildren(
...layers.map(layer => {
const img = document.createElement("img");
img.src = layer.url;
img.style.zIndex = String(layer.layerIndex);
return img;
}),
);
});

const unsubscribeBusy = controller.subscribeBusy(busy => toggleSpinner(busy));
const unsubscribeError = controller.subscribeError(error => {
if (error) showError(error);
});

// On teardown:
unsubscribeData();
unsubscribeBusy();
unsubscribeError();
controller.destroy();

Each Visualization2DLayer has:

  • layerIndex — position in the stack; lower renders below higher
  • url — resolved media URL to use as the image source

Resolved media URLs are cached internally, so unchanged layers are not refetched across evaluations. The evaluate call is etag-aware: when the backend reports no change, the current data is left untouched.

API

data

The current resolved layer set (Visualization2DLayer[]), sorted by layerIndex. null before the first evaluation or when the product has no published 2D visualization.

isBusy

true while an evaluation/resolve pass is running.

error

The last error message, or null. Canceled requests are ignored.

subscribe(callback)

Registers a callback that fires with the new Visualization2DLayer[] | null on every update. Returns an unsubscribe function.

subscribeBusy(callback)

Subscribes to busy-state changes. Returns an unsubscribe function.

subscribeError(callback)

Subscribes to error changes (string | null). Returns an unsubscribe function.

refresh()

Forces an immediate re-evaluation. Normally unnecessary since the controller refreshes on configuration changes. Resolves once the pass completes.

destroy()

Cancels the pending debounce, detaches the rules-engine subscription, clears all subscribers, and empties the media-URL cache. Call it on unmount.