Skip to content

Custom Code ​

Page Flow combines visual programming blocks with JavaScript. Use Custom Code and Code Expression blocks when a focused piece of JavaScript is clearer than building the same operation entirely from blocks.

Keep the main workflow visible on the Page Flow canvas. Events, conditions, data operations, Form interactions, and Cloud Flow calls are generally easier to follow when their major steps remain visible as blocks. Custom JavaScript is most useful for a specific calculation, transformation, or operation within that workflow.

This page explains how to choose, edit, validate, and maintain these two blocks. For exact block inputs and generated behavior, see Custom Code Blocks. For the browser-side ioLoop functions available to custom logic, see the Client API.

Choosing Between Custom Code and Code Expression ​

Both blocks run JavaScript in the Page Flow's browser-side runtime, but they serve different purposes.

BlockPurposeOutput
Custom CodeExecute JavaScript statements as part of a flow sequence.Does not directly produce a block output value.
Code ExpressionEvaluate one JavaScript expression and supply its result to another block.Produces a value of type Any.

Use Custom Code when you need statements, intermediate steps, local variables, or a focused call to an available function. Use Code Expression when another block simply needs a computed value.

For example:

  • A workflow that normalizes several input values may use Custom Code.
  • A content block that needs a formatted display value may use Code Expression.
  • A workflow that opens a Form or invokes Cloud Flow should normally keep those actions visible through their supported blocks, with custom code only where it adds clarity.

Custom Code Block ​

The Custom Code block executes JavaScript statements at its position in the generated Page Flow.

Typical uses include:

  • Preparing an object from existing values.
  • Normalizing or formatting a small set of values.
  • Transforming a list for later use.
  • Calling a helper function intentionally available to the flow.
  • Using a documented browser-side ioLoop API for a focused operation.
  • Implementing a calculation that would otherwise require an unnecessarily complex group of blocks.

Example: Normalize Input Values ​

Suppose earlier blocks have supplied a list of category labels and the next workflow step needs consistent values.

A Custom Code block could use ordinary JavaScript such as:

js
const categories = ["  Hardware ", "Software", " services  "];

const normalizedCategories = categories.map((category) =>
  category.trim().toLowerCase()
);

This example illustrates a focused transformation. It does not automatically expose normalizedCategories as an output of the Custom Code block or make it available to later blocks. If the result must be used elsewhere, pass or share it using an intentional mechanism supported by the flow.

How Custom Code Executes ​

The generated Page Flow places Custom Code inline inside a generated block and try/catch structure.

This means:

  • The code runs in the Page Flow's browser-side execution context.
  • It can reference documented runtime APIs and names intentionally available in the surrounding generated flow.
  • Local declarations made with let or const remain scoped to the generated Custom Code block.
  • Errors occurring in the block are logged through the flow runtime logger.

The block does not produce a direct value output. Use the Code Expression block when another block needs an expression result.

Variable Scope and Sharing Values ​

Variable scope matters when you combine Custom Code with other Page Flow blocks.

SituationGuidance
Value is only needed inside one Custom Code blockUse local const or let declarations.
Value already exists in an intentionally available Blockly variableReference that variable according to the generated flow's supported context.
Several flow sections need a reusable procedurePrefer a standard Blockly function/procedure block, with Custom Code inside it if needed.
Runtime data must be shared between custom code sectionsUse documented flow-share functionality where appropriate.
Value must be supplied directly to another block inputConsider a Code Expression block.

The Client API documents $io.system.setFlowShareData and $io.system.getFlowShareData for storing and retrieving shared runtime values. Consult their API reference for the actual parameters and behavior before using them.

Do not assume that a local variable declared in one Custom Code block can be read by a different block. Also avoid relying on temporary variable names generated internally by Blockly. Such names are implementation details, not stable application interfaces.

For related functions, see $io.system in the Client API documentation.

Code Expression Block ​

The Code Expression block evaluates a single JavaScript expression and supplies its result wherever a compatible value input is expected.

Use it for:

  • A computed name or label.
  • A numeric calculation.
  • A Boolean condition.
  • Selecting or transforming a value.
  • Preparing a simple object or array value.

Expression Examples ​

Combine two values:

js
customer.firstName + ' ' + customer.lastName

Check whether a list contains items:

js
items.length > 0

Format a numeric amount for display:

js
Number(total || 0).toFixed(2)

These examples assume customer, items, and total are intentionally available to the surrounding Page Flow. They are not predefined ioLoop variables.

The last expression returns a formatted string. If another block expects a numeric value, use a numeric expression rather than a display-formatting expression.

Expression Rules ​

The Code Expression editor expects one right-hand-side JavaScript expression, not a complete sequence of statements.

Avoid:

  • Multiple statements.
  • Variable declarations followed by a separate result statement.
  • Top-level await.
  • Trailing semicolons.
  • Trailing comments that interfere with the expected expression syntax.

For example, this is suitable for Code Expression:

js
quantity * unitPrice

The following is a sequence of statements and belongs in Custom Code instead:

js
const subtotal = quantity * unitPrice;
const tax = subtotal * 0.08;
const total = subtotal + tax;

If another block needs a calculated total, you can also express the calculation as one clear expression or place the logic in an intentionally available helper function.

Expression Scope and Results ​

The Code Expression block returns a value of type Any. The receiving block determines which values make sense for its input.

At runtime, ioLoop evaluates the expression within a generated local function. Expressions may reference intentionally available names from the surrounding generated flow, including appropriate Blockly variables and same-flow procedures. They should not depend on incidental generated temporary names.

For values explicitly shared by other custom code, the documented $io.system.getFlowShareData API can be used where appropriate.

Keep expressions short enough that their purpose is obvious. When an expression becomes difficult to read, move the multi-step behavior into Custom Code or a reusable Blockly function instead of writing a dense one-liner.

Adding and Editing Custom JavaScript ​

A typical workflow is:

  1. Open the relevant Page or Form in the Page Editor.
  2. Select Flow to open its Page Flow canvas.
  3. Find Custom Code or Code Expression through the toolbox or its Search area.
  4. Add the block at the point where the JavaScript should run or supply a value.
  5. Open the block's editor and enter the JavaScript.
  6. Use the available helper panel or block reference to find supported Project values and APIs.
  7. Review the code, close the editor, and connect the block to the appropriate flow.
  8. Save the Page Flow, then test the behavior in Preview.

A Custom Code block must be part of an appropriate execution path to run. A Code Expression block must be connected where its value is needed. Simply placing either block on the canvas does not make it execute.

For general editing, connections, and canvas navigation, see Editor Basics.

Project-Aware Editor Assistance ​

The Custom Code editor includes JavaScript editing and Project-aware helper information. Depending on the available Project resources and the selected editing context, the helper panel may show:

Helper AreaHow It Helps
Tables and FieldsIdentify available Project data structures and field names.
QueriesFind configured Project queries.
Pages and Page ElementsIdentify existing page items or choose supported element references.
Data DesignsFind visual designs and their relevant elements.
Connections and CommandsLocate configured integrations and their supported commands.
Cloud Flow Web HooksIdentify callable server-side workflows.
ioLoop APIsFind documented functions and API examples.

Available helper actions can include copying names, copying templates or calling examples, selecting Page Elements, and opening API documentation.

Use these helpers instead of guessing object names, command names, or API signatures. The available entries reflect the relevant Project configuration and editor context; they are not a guarantee that an operation is permitted for every visitor at runtime.

The Code Expression block uses a more compact expression editor. It is intended for entering and validating a value-producing expression rather than a series of JavaScript statements.

Using ioLoop APIs in Custom Code ​

Page Flow custom JavaScript runs in the browser, so use the Client API and other documented interfaces appropriate to that environment.

The Client API includes areas such as:

Client API AreaGeneral Purpose
$io.contentWorking with supported page content.
$io.dbPermitted Project data operations.
$io.domSupported DOM and element operations.
$io.formForm-related operations.
$io.systemRuntime and flow-related functionality.
$io.uiSupported user-interface interactions.

Refer to the Client API for individual functions, parameter types, and returned values.

Do not invent calls based on internal implementation details or assume that a server-side API is available in browser-side Page Flow. A custom JavaScript block does not bypass Project Database permissions, Form configuration, or the supported runtime security model.

Page Flow Blocks, Custom Code, and Frontend Code Assets ​

There are several ways to implement frontend behavior. Choose based on the scope and purpose of the logic.

ApproachBest For
Visual Page Flow blocksEvents, conditions, navigation, Form workflows, data operations, and the main sequence of visible behavior.
Custom CodeA focused group of JavaScript statements inside an existing Page Flow sequence.
Code ExpressionOne calculated value used as an input to another block.
Blockly functions/proceduresReusing logic within the flow.
Frontend Code assetsReusable JavaScript or CSS intended for inclusion on one or more Pages.
Cloud FlowTrusted server-side processing, protected credentials, and server-enforced business rules.

Frontend Code assets are managed in the Project Editor's Code area and can be selected for inclusion through supported Page Settings. A Page Flow can use a helper made available by an included JavaScript asset, provided that it is accessible in the Page's runtime context.

Keep dependencies explicit. If custom code calls a helper from a Code asset, the Page must include the appropriate asset, and the helper must be available when the call runs.

For asset configuration, see Code and Page Settings.

Example: Keep a Workflow Visible ​

Consider a Page that calculates a display summary from an order and updates a Text element.

A clear division of responsibilities is:

text
Order selection event
  Read the selected order
  Calculate the display summary
    Use a focused Code Expression or helper
  Update the summary Text element
  Show a useful error if the data request failed

This is a conceptual example, not the exact labels of particular Page Flow blocks.

The event, data request, and content update remain visible as blocks. Only the focused calculation is expressed in JavaScript.

Save-Time Validation ​

When you select Save in Page Flow, ioLoop validates enabled Custom Code and Code Expression blocks before saving and generating the JavaScript used by the Page or Form.

If invalid JavaScript is detected, the save is stopped and the editor reports an error so you can correct the affected block.

SituationExpected Consideration
Invalid JavaScript in an enabled Custom Code blockCorrect the statements before saving.
Invalid Code Expression syntaxReplace the invalid statements or syntax with one valid expression.
Disabled custom-code blockThe disabled block is excluded from this save-time validation path while it remains disabled.
JavaScript passes validationSave can proceed, but runtime behavior still requires testing.

The validation check does not guarantee that referenced data exists, a function is defined at runtime, a visitor has permission to run an operation, or an external service will succeed.

Disabled Blocks ​

Disabling a block can help temporarily isolate logic during testing. It also means the disabled block's behavior is not part of the active flow.

Do not treat disabling an invalid block as a permanent fix. If you later enable it, correct the code and save again. Confirm that all intended blocks are enabled before publishing.

Unsaved Changes and Publishing ​

Saving Page Flow updates its development version. It does not, by itself, publish the changes to the live application.

Use Preview to verify the saved behavior. When it is ready for release, use Publish Project and check the published experience.

For details, see Editor Basics and Previewing and Troubleshooting.

Runtime Errors and Troubleshooting ​

Code can pass syntax validation and still fail during execution because of unexpected values, missing dependencies, permission errors, or a service failure.

The generated Custom Code block executes inside a try/catch structure, with runtime errors logged through the flow runtime logger. This does not automatically provide a complete user-facing recovery experience. Configure appropriate feedback and flow behavior for the operation.

Common issues include:

SymptomWhat to Check
Page Flow does not saveLook for syntax errors in enabled Custom Code or Code Expression blocks.
Code Expression is rejectedConfirm it is one expression, without a trailing semicolon or unsupported top-level await.
A value is unavailable in another blockCheck variable scope; a local let or const in Custom Code is not automatically shared.
An expression refers to an undefined nameConfirm the referenced variable or function is intentionally available at runtime.
Code appears not to runVerify that the block is enabled and connected to the correct event or execution path.
A helper function cannot be foundCheck the included Code asset and whether the helper is accessible in the Page runtime.
A Client API call failsConfirm its documented parameters, runtime context, and the current user's permitted access.
A result arrives later than expectedReview asynchronous completion handling rather than assuming the next statement waits automatically.
Saved changes do not appear publiclyVerify that the Page Flow was saved and the updated Project was published.

When debugging, narrow the issue to one block or short sequence. Confirm the values entering it, then confirm what the next block actually receives.

For broader runtime investigation, see Previewing and Troubleshooting.

Security and Runtime Boundaries ​

Custom JavaScript in Page Flow runs in the browser. Application visitors can inspect and potentially manipulate browser-side behavior, so it must not be the sole enforcement mechanism for sensitive operations.

In particular:

  • Do not include private API keys, passwords, or provider secrets in Page Flow code or frontend Code assets.
  • Use Database permissions for supported client-side data access.
  • Use Cloud Flow or another trusted Backend capability when authorization, protected credentials, or business rules require server-side enforcement.
  • Treat values from Page inputs, shared Form context, URL parameters, and browser state as untrusted input when performing protected operations.
  • Avoid building custom authorization rules by merely hiding an element or disabling a Button.

Custom Code can extend the browser-side experience, but it does not turn that code into a trusted server-side operation.

Good Practices ​

  • Keep the workflow visible. Use blocks for the main events, actions, and result handling.
  • Keep JavaScript focused. Prefer short, readable statements and expressions over large hidden workflows.
  • Use meaningful names. Give variables and functions names that communicate their purpose.
  • Use documented APIs. Verify names, parameters, and runtime support before calling functions.
  • Manage scope intentionally. Share values through supported mechanisms instead of relying on incidental generated names.
  • Use Blockly functions for reusable flow logic. Use included Code assets when shared frontend JavaScript is more appropriate.
  • Validate and preview. Save-time syntax checking is only one part of testing.
  • Keep protected work on the server. Put secrets, sensitive authorization, and trusted business rules in Backend capabilities.

Common Mistakes ​

Avoid these patterns:

  • Putting an entire Page Flow into one large Custom Code block.
  • Using Code Expression for multiple JavaScript statements.
  • Including a trailing semicolon in an expression.
  • Assuming local Custom Code variables are visible to every other block.
  • Depending on Blockly's internal generated temporary variable names.
  • Assuming every JavaScript or ioLoop API is available in every runtime.
  • Calling a helper from a Code asset without including or exposing that helper to the Page.
  • Treating successful save-time validation as proof that the code will work in Preview.
  • Hiding client-side secrets or protected authorization decisions inside custom JavaScript.
  • Failing to test enabled and disabled blocks after making changes.

Custom Code and Code Expression work best as focused extensions to a readable Page Flow. Use visual blocks to communicate the application's behavior, use JavaScript for the parts it expresses most clearly, and verify the complete result in Preview.