Portal Community

Opening the Editor

1
Select a widget on the canvas
2
In the Properties Editor on the right, scroll to the Custom JS section
3
Click Open Editor to open the full-screen Monaco editor for this widget
4
Write your script in the editor. The editor auto-saves on close.

Editor Events — Choosing When Your Script Runs

Each Custom JS script is attached to a widget event. Select the event from the dropdown at the top of the editor:

EventWhen it firesCommon use
onLoadOnce, when the widget first loads its dataCompute derived variables from initial data
onDataChangeEvery time the widget's data source reloadsTransform data before display; update app variables
onRenderEvery render cycle (use sparingly)Dynamic chart series transformation
onUserActionWhen the user interacts (row click, button press)Custom action logic; complex conditional navigation

Auto-Complete and Type Hints

The editor provides IntelliSense for the App Studio sandbox API. Type widget. or variables. to see available methods and properties with inline documentation:

// Editor auto-completes the sandbox API:
widget.         // → .data, .props, .widgetId, .type
variables.      // → .get(name), .set(name, value), .getAll()
actions.        // → .navigate(path), .openModal(id), .triggerWorkflow(id, inputs)
context.        // → .userId, .tenantId, .roles, .displayName, .email

Inline Error Markers

The editor shows red underlines for:

Test Runner

The editor includes a Test button that runs the script in the sandbox with the current widget's data from the canvas. The output panel shows:

// Example script with console.log for debugging
function onDataChange(widget, variables, actions, context) {
  const rows = widget.data.rows;
  console.log('Row count:', rows.length);

  const total = rows.reduce((sum, r) => sum + (r.dealValue || 0), 0);
  console.log('Total deal value:', total);

  variables.set('totalDealValue', total);
}

Script Structure

Each Custom JS script must export a function matching the selected event name:

// Template for an onDataChange script
function onDataChange(widget, variables, actions, context) {
  // widget  — current widget's data and props
  // variables — read/write app variables
  // actions — trigger app actions
  // context — current user's identity and roles

  // Your logic here...
}