Skip to main content

Event reference

All FPD events are plain DOM CustomEvents dispatched on document. The payload is always in event.detail. Subscribe from any theme script:

document.addEventListener('fpd:price:change', (e) => {
console.log('Extra price is now', e.detail.elementPrice);
});

Events the frontend emits

EventPayload (detail)When
fpd:view:modified{ isCustomized, element }A canvas element was modified. isCustomized tells you whether the product now counts as customized.
fpd:element:added{ element }An element was added to the canvas.
fpd:element:removed{ element }An element was removed.
fpd:view:selectedThe active view changed.
fpd:layout:applied{ layoutIndex, layout }A layout was applied to the current view.
fpd:price:change{ elementPrice }The customization price changed. elementPrice is the extra on top of the base variant price.
fpd:history:changed{ type: 'append' | 'clear' | 'undo' | 'redo' }Undo/redo history changed.
fpd:addToCartthe added product objectThe product was added to the cart without a reload/redirect (only fired with the trigger_event after-add-to-cart strategy). Your cue to update cart UI.
fpd:addToCartButtonState{ disabled }The add-to-cart button was enabled/disabled (e.g. "disable until customized").
fpd:atcPreparedthe complete line item properties object incl. id (variant ID)The design was stored and all line item properties are built — cart adding is handed over to your code (only fired with the lic-event add-to-cart strategy).
fpd:url-changedthe new URL (string)The product URL or ?variant= changed (variant switch, SPA navigation).

Events the frontend listens for (dispatch these from your theme)

EventDispatch when
fpd:cartChangedYour code re-rendered a JS cart/drawer — FPD re-scans it and swaps preview images and edit links.
fpd:input:updateYour external width/height inputs (dynamic views) changed — FPD re-reads them and resizes the view.
fpd:previewYou want the bulk-order preview image regenerated (debounced ~1 s).
document.dispatchEvent(new CustomEvent('fpd:cartChanged'));

URL / history integration

The frontend patches history.pushState and history.replaceState and dispatches fpd:pushstate / fpd:replacestate on window (and listens to them plus popstate). Practical consequence: if your theme changes the variant via history.pushState(...) with a ?variant= URL, FPD picks the change up automatically — no extra wiring needed.

Designer-level events

For fine-grained designer events, subscribe directly on the designer instance once it exists:

FPD.instance.addEventListener('ready', () => { /* designer fully loaded */ });
FPD.instance.addEventListener('productCreate', () => { /* product (re)loaded */ });

Available instance events: ready, productCreate, elementAdd, elementModify, elementRemove, viewSelect, priceChange, historyAction. The fpd:* document events above are the stable, integration-facing projection of these — prefer them when both exist.