The only element required to write your own JavaScript field is an HTML file located in a Magnolia module.

Check out some samples here.

Color picker example

<!DOCTYPE html>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <input id="input" type="color" />
      let input = document.getElementById('input');
      let correlationId;

      function loadStyle(href){
        const link = document.createElement('link');
        link.rel  = 'stylesheet';
        link.type = 'text/css';
        link.href = href;

      window.addEventListener( (1)
        function (event) { (2)
          if ( === 'init') { (3)
            correlationId =;
            input.value = || || '';
            loadStyle( + "/VAADIN/themes/resurface-admincentral/styles.css?v=8.13.1"); (8)

      input.addEventListener('change', function () { (4)
          action: 'changeValue', (5)
          correlationId, (6)
          value: input.value (7)
        }, '*');
1 To initiate the communication between Magnolia and the <iframe>, we need to listen on the message event.
2 Data sent in the message event from the parent window can be:
  • action - to define what action should be triggered

  • correlationId - it will prevent mixing up messages between the different Javascript fields. It is very important to store it for further communication with Magnolia

  • state - represents the data exchanged between the Backend field and the Javascript field

3 Action can have different values:
  • init to initialize the field properties and values

  • error to notify the field failed the validation (either via the required flag or a validator)

  • change to notify the field about any changes in dialog

4 To update the field value on the Magnolia side, the Javascript field needs to send the value back.
5 action types that can be send to parent window are:
  • changeValue - to update the value on Magnolia side

  • changeHeight - to update the height of the field iframe element

6 The correlationId is very important, it will prevent mixing up messages between the different Javascript fields
7 The value hosts the updated value of the field.
  • For changeValue, the type of the value is always a String. If you need to store complex objects, stringify it before returning it to Magnolia.

  • For changeHeight, send the height in pixels that the new <iframe> will be.

8 Optional. If your html wants to load js/css delivered by magnolia but apart from your light-modules webresources-folder, use the provided contextPath and loadStyles-method in order to get independent of your magnolia-installation.