App Studio
Triggering Actions
The actions API lets Custom JS trigger the same App Studio actions available in the no-code builder — navigate, open modal, trigger workflow, show notification. This is useful for implementing conditional navigation or complex event-driven UI flows.
actions.navigate()
// Simple navigation
actions.navigate('/leads');
// Navigate with a computed path
function onUserAction(widget, variables, actions, context) {
const selectedRow = widget.selectedRow;
if (!selectedRow) return;
actions.navigate('/leads/' + selectedRow.id);
}
// Navigate with options
actions.navigate('/leads/' + id, { mode: 'replace' });
actions.navigate('/leads/' + id, { mode: 'new-tab' });
// Navigate with query params (append to the path string)
actions.navigate('/leads?status=active&owner=' + context.userId);
actions.openModal()
// Open a modal by its widgetId
actions.openModal('confirm-delete-modal');
// Open with params (passed as modal variables inside the modal)
actions.openModal('lead-detail-modal', {
leadId: widget.selectedRow?.id,
mode: 'view'
});
// Inside the modal, access params as:
// {{ modal.leadId }}
// {{ modal.mode }}
actions.closeModal()
// Close the currently open modal
// Typically used in a confirm/cancel button Custom JS
function onUserAction(widget, variables, actions, context) {
actions.closeModal();
}
actions.triggerWorkflow()
// Trigger a workflow and handle the result
function onUserAction(widget, variables, actions, context) {
const row = widget.selectedRow;
actions.triggerWorkflow('ArchiveLead', {
leadId: row.id,
archivedBy: context.userId
}).then(function(result) {
if (result.success) {
actions.showNotification('Lead archived successfully', 'success');
actions.navigate('/leads');
} else {
actions.showNotification('Archive failed: ' + result.error, 'error');
}
});
}
actions.showNotification()
// Show a toast notification
actions.showNotification('Changes saved', 'success');
actions.showNotification('Please fill all required fields', 'warning');
actions.showNotification('An error occurred', 'error');
actions.showNotification('Processing...', 'info');
// Variants: 'info' | 'success' | 'warning' | 'error'
Conditional Action Trigger
// Navigate to different destinations based on computed logic
function onUserAction(widget, variables, actions, context) {
const row = widget.selectedRow;
if (!row) return;
// Complex condition not expressible in a simple token expression
const isHighValue = row.dealValue > 50000;
const isAdmin = context.roles.includes('admin');
if (isHighValue && !isAdmin) {
actions.showNotification('High-value leads require admin approval', 'warning');
actions.openModal('request-approval-modal', { leadId: row.id });
} else {
actions.navigate('/leads/' + row.id + '/edit');
}
}
Actions are async — use .then()
All
actions.* calls return Promises. The sandbox does not support top-level await or async functions — use .then() for result handling. For navigation and notifications, you don't need to handle the return value.