¶ Canvas Items And CanvasBuilder
This chapter explains the practical authoring model behind Jetstack canvases:
- how CanvasBuilder works
- what a canvas item is
- how item settings are stored
- how nested items, active areas, scopes, and runtime values work
- which item families are available and when to use them
Use this chapter after reading:
Most of the real power of canvases does not live in the top-level canvas form. It lives in the item tree edited in CanvasBuilder.
If you understand CanvasBuilder well, you can:
- assemble full pages
- embed views, forms, and nested canvases
- work with object context
- prepare variables for later items
- build reusable fragments
- create property-oriented templates
A canvas is a tree of items.
Each item has:
- a stable generated item ID
- a title used in the builder
- a class defining what the item does
- input parameters that control its behavior
- optional child zones called active areas
- optional hidden state
- optional elevated-permissions state
At runtime, the canvas renderer walks the tree and asks each item to produce HTML.
The result is not a flat HTML template authored by hand. It is a structured composition graph stored as serialized item objects.
CanvasBuilder is the dedicated authoring interface for the item tree.
Its main working areas are:
- the item gallery on the left
- the editable canvas area on the right
- the draft indicator and publish controls
- the meta dialog
- the item settings modal
- the parameter-arguments modal
CanvasBuilder loads the draft if one exists. Otherwise it loads the published content.
This means:
- edits normally go into
content_draft
- the live canvas keeps using
content until you publish
The builder exposes:
Use this workflow when:
- the canvas is already live
- you want to iterate safely
How it works:
- drag or drop from the item gallery into the main canvas or into an item's active area
What it means:
- the builder creates a new item instance of the chosen class
- if added into a child zone, the item becomes part of that parent item's active area
How it works:
- drag an existing item to a new position or zone
What it means:
- the builder reorders the serialized tree or moves the item to a different active area
How it works:
- use the item's copy action
What it means:
- the item is cloned
- the copy receives a new item ID
- child items also receive regenerated IDs
Use it when:
- a block should be duplicated and then adjusted
How it works:
- use the delete action on the item
What it means:
- the item is removed from the canvas tree
- child items inside it are removed with it
How it works:
- change the item title in the builder
What it means:
- the title improves builder readability
- it usually does not change runtime behavior directly
Use titles generously for:
- repeated similar items
- layout sections
- nested forms
- reusable snippets
How it works:
- click the link-icon button next to Change title in the item's edit controls
- enter a free-form identifier (e.g.
my-card, profile-row)
- the current value is shown as a small badge; click the badge to copy it
What it means:
- the rendered wrapper element gets
data-soopio-id="<your-id>"
- Run JavaScript automation code can target it via
Jetstack.getElement('<your-id>') or Jetstack.getElements('<your-id>')
- the Public ID survives duplication and is independent of the internal item ID and any HTML
id input parameter
- when the item is rendered inside an iterator, each row gets
<your-id>#<iteratorUniqueId> — use Jetstack.getElements to match every row
Use Public IDs for any canvas item you plan to reference from a RunJavaScriptAction.
How it works:
- toggle the hidden flag in the builder
What it means:
- hidden items do not render in runtime mode
- they can still remain in the builder tree for later use or temporary suppression
Use it when:
- testing alternatives
- parking a block temporarily
- disabling one section without deleting its configuration
How it works:
- toggle the item's elevated-permissions flag
What it means:
- the item can request a more privileged execution mode in the places that honor this flag
- this is especially relevant for some form and operation items
Use it carefully:
- elevated permissions are a governance decision, not only a convenience setting
Every item class defines its own configuration through input parameter definitions.
Those definitions can specify:
- parameter name
- expected type
- default value
- UI control type
- conditional visibility
- redraw-on-change behavior
- value picker type
- context for resource pickers
- whether the value should be sandboxed before rendering
Most items inherit several common parameters.
What it controls:
- HTML class added to the wrapper output
Use it when:
- a block needs styling hooks
- a custom wrapper class improves CSS targeting
What it controls:
- HTML ID added to the rendered wrapper
Use it when:
- a block needs a DOM anchor or JS hook
What it controls:
- whether the item should be redrawn during AJAX updates
Use it when:
- the item output depends on state that changes during AJAX operations
What it controls:
- whether the item should expose itself as reloadable content
Use it when:
- the item is a content region that should be refreshable after interactions
What it controls:
- whether the item should repeat over an iterable source
Why it matters:
- this is one of the key ways canvases become data-driven
- iterated items gain iterator context for nested content
An active area is a named child zone inside an item.
Examples:
- a
Row has an inner area for columns
- an
If item has if_true and if_false
- a
Card has areas for body-like child content
- a
CustomForm has an inner area for fields
Why it matters:
- active areas are what make nesting possible
- they let layout and structural items act as containers rather than only leaf nodes
Use them to:
- create layout structure
- separate conditional branches
- embed fields inside forms
- build nested fragment hierarchies
Canvas item input parameters are not limited to plain text.
In practice, a value can be:
- a literal scalar
- an array
- a selected platform resource such as a type, view, query, or automation
- a scope path resolved by CanvasScopeResolver
- a string containing scope substitutions
- a string containing expression execution
This is one of the most important things to understand about CanvasBuilder.
Some parameters declare a valueType, which means the builder treats them as references to platform resources.
Common picker types include:
- automation
- canvas
- email template
- module
- property
- query
- role
- type
- view
Some also declare a valueTypeContext, which means the valid options depend on another parameter.
Example:
- a property picker may use
typeId as its context so the builder knows which type's properties to offer
Item parameters can appear or disappear depending on other parameter values.
Examples:
- the canvas item's advanced selector is shown only when the main canvas selector is set to
_advanced_
- the embedded view item shows different fields depending on whether it is using a defined view, a query, parameter-built query, or custom SQL
Why it matters:
- the settings UI is adaptive
- you should think of an item as a small stateful configuration object, not a flat form
Some parameters cause the settings table to redraw when they change.
Use this to understand why:
- selecting one mode can reveal entirely different follow-up fields
- changing a base parameter can change available downstream choices
CanvasBuilder uses CanvasScopeResolver to help build dynamic values.
The main top-level keywords exposed by the resolver include:
string
variable
templateVar
canvasVar
parentObject
iteratorItem
dataQuery
object
array
date
dateDiff
true
false
null
formStatus
currentUser
appParameter
emptyString
queryResult
math
randomInt
What this means in practice:
- item parameters can be built from context instead of hard-coded
- the available next fields depend on the selected keyword and current context
Use scope-based values when:
- the item should react to wrapper-object context
- a repeated block needs iterator values
- a variable set by an earlier item should drive later items
- app parameters or query results should influence rendering
See also:
Some scope targets behave like callable fields with arguments.
CanvasBuilder supports this through a dedicated parameter-arguments modal.
Why it matters:
- some selected scope targets are not simple leaf values
- they expose parameters that must be configured for the final resolved value to make sense
Use it when:
- the builder offers an arguments modal for the selected parameter path
¶ String Interpolation And Expressions
Many string-valued parameters support two useful runtime patterns.
Strings can include scope substitutions using a {$...} form when the referenced path is resolvable through the canvas scope model.
Use this when:
- a text block should inject a field value
- a link label should reflect current context
- a title should include dynamic data
Strings can also include {=...} fragments evaluated through the code processor.
Use this when:
- a rendered string needs expression-driven transformation
- you need a calculated textual result rather than only a direct scope lookup
See:
The item gallery is grouped by capability. The exact classes come from the canvas item registry, but in practice the gallery is organized around these families.
These items define structure and placement.
Common layout items:
If
Block
Row
Col
Spacer
Card
Tabs
Use them when:
- you need layout hierarchy
- content should be conditionally shown
- sections should be visually grouped
- the canvas needs a clear page structure
Special note on If:
- it has
if_true and if_false child areas
- it is a structural branching tool inside the canvas itself
These items render content-oriented structures.
Common content items:
Table
Table custom
Tr
Td
TableGeneralIterator
TableQueryIterator
H1 to H6
P
Span
Image
Link
Use them when:
- the canvas needs textual or media content
- you want manual tabular structure
- repeated content should be rendered row by row
These items work with object context and object rendering.
Common object items:
Object wrapper
Object render
Property value
Object overview
Object comments
GeneralIterator
QueryIterator
Why they matter:
- they are the main bridge between the canvas and Jetstack's data model
Use it when:
- a subtree should work against one current object context
- child items need
parentObject access
Use it when:
- you want the platform to render a whole object surface inside the canvas
Use it when:
- a canvas should display one specific field from an object
Use them when:
- one block should repeat over a general iterable or query result
- child items should gain iterator context
These items are general-purpose compositional helpers and integrations.
Common widget items:
Set variable
Set variable by Automation
Set variable by Callback
View
Canvas
Custom HTML
Replicator item template
Use them when:
- later items need a prepared canvas variable
- a preload automation would be too broad for one local value
Use it when:
- a canvas should embed a normal Jetstack view
Its main modes are:
- defined view
- dynamic view with defined query
- dynamic view from query parameters
- dynamic view from custom SQL
This makes it one of the most important bridge items between canvases and views.
Use it when:
- one canvas should render another canvas
This is the main composition mechanism behind snippet-like reuse.
Use it when:
- the layout needs custom markup that is still anchored inside the canvas item model
Important behavior:
- it supports a gallery of nested child elements exposed through shortcodes
- it also supports injected variables
Use it carefully:
- prefer structured items where possible
- reach for custom HTML when the structured item palette is not expressive enough
Use it when:
- building property-oriented repeated-entry layouts, especially for replicators
These items build custom forms and form fields inside canvases.
Common form items:
Custom form
Form
CustomFormField
FormField
FormLabel
FormControl
Why they matter:
- forms are one of the strongest reasons to use canvases
- they let you build custom entry and editing flows with automation hooks
Use it when:
- the canvas should host a fully custom form layout and field set
Use it when:
- the canvas should host a structured object form tied to a type and form mode
Form items can wire automations to events such as:
- anchor
- reload
- validate
- submit
- success
- after success
- error
This makes forms inside canvases highly composable with the automation system.
Use this rule of thumb:
- choose Layout items to shape space
- choose Content items to render text, media, or manual structure
- choose Object items to bind the canvas to domain data
- choose Widget items to compose behavior and embed other platform surfaces
- choose Form items when the canvas becomes an input flow
Typical structure:
Object wrapper
- layout items for sections
- property-value or object-overview items
- embedded view blocks for related records
Use it for:
- detail pages
- rich object dashboards
Typical structure:
- a small layout skeleton
- a few object-aware or variable-aware items
- optional custom HTML for tight presentation
Use it for:
- shared summary blocks
- headers
- reusable side sections
Typical structure:
- small layout
- one or two variable-setting items
- one embedded view or KPI-oriented fragment
Use it for:
- dashboards
- role-specific summary panels
Typical structure:
Custom form or Form
- field items
- automation hooks on anchor, validate, submit, and success
Use it for:
- guided entry flows
- custom object editing experiences
- property-level repeated-entry templates
- Use titles on items so the tree stays understandable.
- Keep one clear responsibility per item whenever possible.
- Prefer structured items before custom HTML or callback code.
- Use snippet canvases to avoid duplicating large blocks.
- Keep variable-setting items close to the sections that use them.
- Use iterators deliberately and make sure nested content clearly depends on them.
- Treat elevated permissions as an exception, not a default.
- Publish intentionally and use drafts for experimentation.
- Does this canvas really need a custom block here, or would a standard embedded view be better?
- Should this value be hard-coded, scoped, or computed?
- Does this subtree need object context or iterator context?
- Would a reusable snippet be better than repeating the same block in several canvases?
- Is custom HTML solving a real limitation, or hiding an avoidable design problem?