Docs  /  Integrations  /  JavaScript API (V3)

JavaScript API (V3)

Last updated: 20. October 2026

With the JavaScript API you connect the configurator to your own logic on the page: show the price in your purchase bar, transfer the selection into your own form, set values from outside, or save a configuration and reopen it later. The V3 frontend engine provides the window.Configento object for this – no matter whether it gets onto the page via the HTML snippet or a shop plugin. This guide uses ready-made examples to show how to solve typical tasks and how to move code written for the Legacy engine to V3. Every method with its signature, all events, data types and settings are listed in the JavaScript API reference (V3).

Where the API is available

window.Configento exists wherever the page loads the V3 engine:

Integration JavaScript API
HTML snippet (card HTML5 (V3 Beta)) Always
Shopify Always
PrestaShop Always
Magento 2 When the component is set to V3 (Beta) or requires V3, see Frontend Engine: Legacy or V3
Shopware 6 and the classic HTML5 snippet No – both load Legacy

The plugins use the API themselves, for example to put price and configuration into the cart. Your own code runs alongside – you don't need to switch anything off.

Getting started

<script>
  window.addEventListener('DOMContentLoaded', function () {
    Configento.ready.then(function () {
      var configurator = Configento.first();

      configurator.on('price', function (p) {
        document.querySelector('#my-price').textContent = p.total.toFixed(2) + ' ' + p.currency;
      });

      configurator.on('change', function () {
        console.log('Width:', configurator.getValue('width'));
      });
    });
  });
</script>

Three rules that avoid almost all problems:

  1. Wait for Configento.ready. Only then have all configurators on the page loaded. If you call a method before that, it reports that the configurator isn't ready yet.
  2. window.Configento only exists once the configento.js script has run. It's loaded with defer, i.e. after the page has been built. So start your code on DOMContentLoaded or later – not directly in a script in the <head>.
  3. The configurator looks for its places only once, on load: every element with data-configento. Elements your code inserts later are not picked up.

You address characteristics by their internal name (ID), values by the Value field. The numeric IDs work as well.

Loading faster and reserving space

Three settings on the element with data-configento help while the page builds up:

Attribute Effect
data-configento-min-height="640px" Reserves the height while the configurator loads – the page below doesn't jump when the first step appears. Afterwards the height adapts again.
data-configento-min-height-keep Keeps the height afterwards as well
data-configento-component-json='{…}' The component directly in the page, exactly as GET /api/v3/components/{id} returns it. Then there's no request on load. Only useful if your page keeps the published version up to date on the server side – after publishing, the page has to deliver the new version.

In the JSON attribute data-configento-config they're called minHeight, minHeightKeep and component.

It's also worth adding a hint in the <head> that tells the browser to open the connection to the cloud early:

<link rel="preconnect" href="https://cloud.configento.app" crossorigin>

The configurator loads the component as soon as the script starts. Returning visitors don't load it again: if it hasn't changed since their last visit, the server just briefly confirms that.

Showing the price in your purchase bar

window.addEventListener('DOMContentLoaded', function () {
  Configento.ready.then(function () {
    var k = Configento.first();
    var field = document.querySelector('#purchase-bar-price');
    k.on('price', function (p) {
      field.textContent = p.total.toLocaleString('en-GB', { style: 'currency', currency: p.currency });
    });
  });
});

price arrives once right after loading and then on every price change. Without code of your own, data-configento-price-mount="#purchase-bar-price" works too – then the configurator draws the price into your element itself.

Transferring the selection into your own form

For an inquiry via your own form, you validate the configuration with finalize() and write the result into hidden fields:

<form id="inquiry" action="/inquiry" method="post">
  <input type="hidden" name="configuration">
  <input type="hidden" name="summary">
  <input type="hidden" name="sku">
  <input type="hidden" name="price">
  <button type="submit">Request a quote</button>
</form>

<script>
  document.querySelector('#inquiry').addEventListener('submit', function (e) {
    e.preventDefault();
    var form = e.target;
    var k = Configento.first();
    k.finalize().then(function (result) {
      if (!result.ok) return; // the errors are now shown on the characteristic
      form.configuration.value = JSON.stringify(result.payload);
      form.summary.value       = k.getSummary({ format: 'text', separator: '\n' });
      form.sku.value           = k.getCombinedSku();
      form.price.value         = result.priceTotal;
      form.submit();
    });
  });
</script>

finalize() shows missing required fields and errors from rules on the characteristic, just like the action button, but doesn't send anything itself. getCombinedSku() returns the combined article number from the selected values, e.g. CL-W-GR; it's also in result.payload as _combined_sku.

Presetting values

You address characteristics by their internal name, values by the Value field:

Configento.ready.then(function () {
  var k = Configento.first();
  k.selectValue('colour', 'anthracite');    // select, radio buttons, list with images
  k.toggleValue('accessories', 'crank');    // checkbox, multi-selection
  k.setText('width', '120');                // input field
  k.setQuantity('screws', 'm6', 4);         // multi-selection with quantities
});

Every call works like a click by your customer: rules, formulas and price are recalculated. With resetSelection('colour') you reset a characteristic.

From the address: this is how you take over ?colour=anthracite&width=120:

var params = new URLSearchParams(location.search);
if (params.has('width'))  k.setText('width', params.get('width'));
if (params.has('colour')) k.selectValue('colour', params.get('colour'));

Variant changed in the shop: if formulas depend on product attributes such as width or weight, you pass on the new values with k.setProductAttributes({ width: '140' }). The selection stays, everything is recalculated. The initial values go into the JSON attribute as "productAttributes" when embedding.

Changing the language

If the language selection is switched on, showLanguageSelect() shows the flags again – for example for a "Change language" button:

<button type="button" onclick="Configento.first().showLanguageSelect()">Change language</button>

The current selection in the configurator is kept; after the new pick it continues in the new language. Without the language selection switched on, or for a component with only one language, nothing happens. You may also call the method before the configurator has loaded.

Controlling the wizard and groups

With the Tabs layout and in the Wizard, the configurator always shows one group. With these methods you build your own step display:

<ol id="steps"></ol>

<script>
  Configento.ready.then(function () {
    var k = Configento.first();
    var list = document.querySelector('#steps');

    function render() {
      var active = k.getActiveGroup();
      list.innerHTML = '';
      k.getGroups().forEach(function (group) {
        var item = document.createElement('li');
        item.textContent = group.title;
        if (active && group.id === active.id) item.className = 'active';
        item.onclick = function () { k.setActiveGroup(group.id); };
        list.appendChild(item);
      });
    }

    render();
    k.on('group', render);   // after every step change
    k.on('change', render);  // rules can show and hide groups
  });
</script>

getGroups() returns the groups shown with id, key, index and title, getActiveGroup() the current one. setActiveGroup() switches by ID or internal name and, going forward, checks every step on the way like Next; nextGroup() and prevGroup() correspond to Next and Back.

key is the group's internal name. You assign it in the editor in the group's settings under Internal name (ID), e.g. vehicle. Unlike the position, it stays the same when you reorder groups or a rule hides a group, and it reads better in code than a number. The element of the group shown also carries it as data-configento-group-key.

Your own check before the step changes

With setStepGuard() you run your own check before your customer moves on – for example a date of birth or a vehicle identification number. The check runs after the built-in required-field check, and only forward:

k.setStepGuard(function (step) {
  if (step.from.key !== 'holder') return true;
  if (isOfAge(k.getValue('date_of_birth'))) return true;
  return [{ characteristic: 'date_of_birth', message: 'The holder must be of legal age.' }];
});

true lets the customer move on, false holds them without a message, a list holds them and shows each message on the named characteristic. The function may also return a promise, for example for a check over the network; until the answer arrives, Next and Back are locked. If it throws an error, the step changes anyway – your customer shouldn't get stuck.

Turning off the built-in navigation

If you build the step display yourself, hide the built-in one:

data-configento-wizard-nav Effect
full (default) Tabs, progress bar, Back and Next
buttons Only Back and Next
none None of it – your code controls the steps

The same setting is available in the editor under Settings → General → Group layout → Wizard navigation (V3); the attribute on the element takes precedence.

Saving and reopening a configuration

storeAsset() saves the current configuration and returns { id, url }. With the id you build a deep link: the address of the product page with ?dl= and the id. When someone opens this address, V3 restores the configuration in the first configurator on the page by itself.

k.storeAsset().then(function (saved) {
  var link = new URL(location.href);
  link.searchParams.set('dl', saved.id);
  navigator.clipboard.writeText(link.toString());
}).catch(function (error) {
  if (error instanceof Configento.CloudError && error.code === 'NO_SELECTIONS') {
    alert('Please select something first.');
  }
});

Restoring it yourself – for example in a specific one of several configurators:

Configento.loadAsset(id, { instance: k }).then(function (data) {
  k.restoreFromAssetJson(data);
});

Nothing can be saved in the admin preview (CONFIG_MISSING); test on your website or in the shop. All error codes are listed in the reference.

Your own window for image selection

Some characteristics open a window, for example a list with images in the large view. By default V3 draws this window itself. If it should look like your shop's windows, you pass an adapter:

Configento.setModalAdapter({
  openOverlay: function (args) {
    // args.title, args.container (filled by the configurator), args.onClose
    var modal = myShop.openModal(args.title, args.container, args.onClose);
    return { close: function () { modal.close(); } };
  }
});

Attach args.container to your window and call args.onClose() when your customer closes it. The configurator calls close() when it wants to close the window itself. Set the adapter as soon as window.Configento exists and before your customer opens a window. The Magento plugin already includes an adapter for the Magento windows.

Switching from Legacy

The Legacy engine had its own, older API: settings in the _configentoSettings object, the CONFIGENTO_PRODUCT object, global objects such as Justselling_Configento_App_Api and jQuery events such as configentoUpdateOptionsInDomAfter. When you switch to V3, three things change:

  1. Embedding: instead of _configentoSettings and html5.js you use the V3 snippet with data-configento-* attributes. How is described in HTML Snippet Integration. The token is a different one; it comes from the HTML5 (V3 Beta) card.
  2. Your own code: from now on it addresses window.Configento – or keeps running via the compatibility script.
  3. Features: what only Legacy can do is listed in Frontend Engine: Legacy or V3.

Settings

Legacy (_configentoSettings) V3
_template data-component-id
_customer data-configento-customer
_token data-configento-token – new token from the HTML5 (V3 Beta) card
_cloudbase data-configento-cloud-base-url
_taxrate data-configento-tax-rate
_currencyCode data-configento-currency
_cssPathCombinedImage or .configento-combinedImage data-configento-combined-image-mount
Element #configento-price data-configento-price-mount
Element #configurator1 An element with data-configento
_loadjQuery, _loadChart, _loadDropzone Dropped – V3 brings everything along and doesn't need jQuery

You no longer need _debug, _development, _cloudport and _productOptionId.

Option 1: Compatibility script

Shop themes in particular have accumulated code over the years that accesses the old objects. To keep it running under V3, you additionally load configento-compat.js before configento.js:

<script src="https://cloud.configento.app/configento-v3/configento-compat.js" defer></script>
<script src="https://cloud.configento.app/configento-v3/configento.js" defer></script>

The Magento plugin loads it by itself with V3. The script takes over:

Legacy What the script makes of it
Events configentoUpdateOptionsInDomBefore/…After and configentoUpdateHeaderInDomBefore/…After Fired on document on every change – reachable with jQuery .on() and with addEventListener
CONFIGENTO_PRODUCT.setPrice(price) Called with the total price on every price change – provided your page defines CONFIGENTO_PRODUCT
Element #configurator1 Becomes the place for the configurator; the component ID comes from CONFIGENTO_PRODUCT.getTemplateId()
Justselling_Configento_App_Helper.getConfigurator(), getBackendUrl() Return the V3 configurator and the cloud address respectively
Justselling_Configento_App_Webshop.finalizeAction(done) Validates with finalize(), writes the configuration into the cart's hidden form fields and then calls done
Justselling_Configento_App_CloudAsset.storeCloudAsset(…) Saves with storeAsset(). The callback only receives the ID, not folder and file name.
Justselling_Configento_App_Wizard.validateForm() and the other validation functions Always return true – validation happens on completion
Justselling_Configento_App_Wizard.setActivateGroup(number) Switches to the group at this position, without a check
setDisableGroup, setEnableGroup, updateWizard Do nothing

If your code has already defined one of these objects itself, your version is kept.

What the script doesn't take over: it doesn't read _configentoSettings and doesn't create CONFIGENTO_PRODUCT – on a plain HTML page, html5.js used to do that. So there you need the data-configento-* attributes in any case. Also not taken over are Justselling_Configento_App_Api, Justselling_Configento_App_Summary and all other events. For those, see the counterparts below.

Option 2: Rewriting for the new API

In the long run, code using window.Configento is clearer: it receives content with the events, throws understandable errors and doesn't depend on element IDs. This is how old and new calls correspond – everything new goes in Configento.ready.then(…) on a configurator k = Configento.first():

Legacy V3
Justselling_Configento_App_Helper.getConfigurator() Configento.first() or Configento.forElement(…)
Justselling_Configento_App_Api.getOptionValue(characteristic) k.getValue('characteristic')
Justselling_Configento_App_Api.setOptionValue(characteristic, value), setOptionValues([…]) Depending on the data type k.selectValue(), k.toggleValue(), k.setText() or k.setQuantity()
Justselling_Configento_App_Api.setEventHook(…) k.on('change', …) – likewise price, finalize, error and group
setEventHook('configentoValidateGroupBefore', fn) (prevent the step) k.setStepGuard(fn)
getConfigurator().getActiveGroup() k.getActiveGroup()
Justselling_Configento_App_Wizard.setActivateGroup(number) k.setActiveGroup(id or internal name)
Event configentoSetActiveGroupAfter k.on('group', …)
CONFIGENTO_PRODUCT.setPrice(price) k.on('price', function (p) { … p.total … }) – or data-configento-price-mount
Justselling_Configento_App_Summary.getSummaryAsText() k.getSummary()
Justselling_Configento_App_Wizard.validateForm() k.finalize() → ok
Justselling_Configento_App_Webshop.finalizeAction(done) k.finalize().then(…)
Justselling_Configento_App_CloudAsset.storeCloudAsset(…) k.storeAsset() → { id, url }
Field #configurator1-header or generateHeaderValue() k.getHeaderValue() (Base64, as before) or k.getAssetPayload() (JSON)
Events configentoUpdateOptionsInDomAfter, configentoUpdateHeaderInDomAfter, configentoApiSetOptionValueAfter k.on('change', …)
Event configentoRenderSummaryAfter k.on('change', …) and k.getSummary() inside it
Event configentoFinalizeActionAfter k.on('finalize', …)
Events configentoRenderAfter, configentoLoadTemplateAfter Configento.ready
Events for charts, preview images and file uploads No counterpart
?dl=… and ?tb=1 in the address Unchanged
Preselecting characteristics via the address, e.g. ?width=120 Not built in – a few lines, see Presetting values

How to preselect characteristics via the address is shown in Presetting values.

Difference in events: the Legacy events only triggered jQuery handlers and mostly delivered no data. The V3 events pass the new selection or the new price directly – you no longer need to read anything from the DOM.

Troubleshooting

  1. Configento is not defined – your code runs before configento.js has loaded. Start it on DOMContentLoaded and wait for Configento.ready. Also check whether the page loads V3 at all (see above).
  2. Configento instance not ready when calling a method – the configurator is still loading. Only call methods inside Configento.ready.then(…).
  3. Configento.first() returns null – there's no element with data-configento on the page, or it was only inserted after loading.
  4. A call like selectValue() throws an error – the internal name or the value is wrong, or the data type doesn't fit the method. Upper and lower case matter; you'll find the name in the editor under Internal name (ID).
  5. storeAsset() reports CONFIG_MISSING – nothing can be saved in the admin preview. Test on your website or in the shop.
  6. Old theme code throws errors like Justselling_Configento_App_Wizard is not defined – the compatibility script is missing or comes after configento.js.

Next steps


← All articles Try free for 14 days