UI templating

The following schema is used to define the UI which appears on the custom configuration forms used for custom plugins.

Using this templating system, you can quickly and easily define which fields are rendered to users and how user-provided values are mapped into a configuration.

Where the schema is used

The same field schema is used in two places, and a few field types only make sense in one of them.

Location
File
Controls
Plugin setup form
ui.json in the plugin folder root
The form shown on the data source configuration page when installing a plugin. Typically used to collect credentials, connection details, or default configuration.
Data stream parameters
The ui array inside a data stream definition
The parameters shown in the tile editor when a user adds that data stream to a dashboard.

In both locations the value is an array of field definitions, even when you only define one field:

[
    {
        "type": "password",
        "name": "apiKey",
        "label": "API key"
    }
]

Two types are specific to data stream parameters, because they depend on a dashboard being present: objects (which selects from the graph) and expression (which reads dashboard variables and timeframe values). Setting tileEditorStep on a field only has an effect in a data stream’s ui array for the same reason.

Common properties

Every field type accepts the following properties.

Property
Type
Description
type
string
The field type. Required.
name
string
The key the entered value is stored under, and the name used to reference it in a Mustache expression such as {{apiKey}}. Required.
label
string
The label shown above the field. Required for most types.
help
string
Tooltip text shown as a (?) icon next to the label. Supports Markdown.
description
string
Explanatory text shown below the field. Available on text, number, radio, switch, toggle, checkbox, autocomplete, json, code, expression and objects.
defaultValue
varies
The value the field starts with. The accepted type follows the field type: a string for text, a number for number, a boolean for toggle.
validation
object
Validation rules. See Validation below.
disabled
match spec or boolean
Greys the field out without hiding it. See Match specs below.
columnWidth
number
Relative width, as an fr unit. Honored only when the field is a child of a field group with "displayAs": "row". Fields without it size to their content.
tileEditorStep
array
Which tile editor step the field appears in. Either ["Parameters"] (the default) or ["Timeframe"].
allowEncryption
boolean
Allows the entered value to be stored encrypted.

Three types are defined independently of this list and accept only their own properties: markdown, objects and script. In particular, none of them accept disabled or columnWidth.

Important

Do not use the title property. It is deprecated in favor of help and has no effect.

Validation

The validation object holds the rules applied to a field’s value before the form can be submitted. Each rule is written either as a plain value, or as { "value": ..., "message": "..." } to supply your own error message.

Rule
Applies to
Description
required
any field
Marks the field as required.
min / max
number
Minimum and maximum allowed value. Also accepts a date string.
minLength / maxLength
text fields
Minimum and maximum number of characters.
pattern
text fields
A regular expression, written as a string, that the value must match.
valueAsNumber
text fields
When true, parses the entered text as a number before validating and submitting.
valueAsDate
text fields
When true, parses the entered text as a date before validating and submitting.

{
    "type": "text",
    "name": "tenantId",
    "label": "Directory (tenant) ID",
    "validation": {
        "required": true,
        "minLength": {
            "value": 36,
            "message": "Must be a 36-character GUID"
        },
        "maxLength": 36
    }
}

Note that min and max on a number field live here, not on the field itself.

Match specs

Three properties take a match spec: matches on an objects field, visible on a field group, and disabled on any field. A match spec describes a set of conditions to test a value against.

A match spec can be written in four ways.

Form
Meaning
"all", "true", or true
Matches everything.
"none" or false
Matches nothing.
An object
A set of clauses, one per property. All clauses must pass.
An array of objects
Several sets of clauses. The spec passes if any set passes.

Inside an object, each key is the property being tested and each value is a clause:

Clause
Passes when
"someValue"
The property equals someValue. Shorthand for equals.
{ "type": "equals", "value": "x" }
The property equals x.
{ "type": "notEquals", "value": "x" }
The property does not equal x.
{ "type": "oneOf", "values": ["x", "y"] }
The property equals one of the listed values.
{ "type": "notOneOf", "values": ["x", "y"] }
The property equals none of the listed values.
{ "type": "contains", "value": "x" }
The property contains x as a substring.
{ "type": "notContains", "value": "x" }
The property does not contain x.
{ "type": "regex", "pattern": "^prod-" }
The property matches the regular expression.
{ "type": "notRegex", "pattern": "^prod-" }
The property does not match the regular expression.
{ "type": "any" }
The property exists, whatever its value.

Where a property holds an array of values, the positive clauses (equals, contains, oneOf, regex, any) pass if any item in the array matches, and the negative clauses (notEquals, notContains, notOneOf, notRegex) pass only if every item matches.

Conditional visibility

visible is only available on a field group, so to show or hide fields conditionally you wrap them in a field group and put visible on the group. A field group with no displayAs renders nothing of its own, its children appear exactly as if they were not grouped, so it works as a zero-cost wrapper that exists only to carry the condition.

[
    {
        "type": "radio",
        "name": "authMode",
        "label": "Authentication",
        "options": [
            {
                "value": "basic",
                "label": "Basic"
            },
            {
                "value": "token",
                "label": "Token"
            }
        ]
    },
    {
        "type": "fieldGroup",
        "visible": {
            "authMode": "basic"
        },
        "fields": [
            {
                "type": "text",
                "name": "username",
                "label": "Username"
            },
            {
                "type": "password",
                "name": "password",
                "label": "Password"
            }
        ]
    }
]

To match more than one value, use a clause:

{
    "type": "fieldGroup",
    "visible": {
        "authMode": {
            "type": "oneOf",
            "values": [
                "basic",
                "digest"
            ]
        }
    },
    "fields": []
}

disabled takes the same match spec, but is a common property, so it can go directly on any field with no wrapper:

{
    "type": "text",
    "name": "region",
    "label": "Region",
    "disabled": {
        "useDefaults": "yes"
    }
}

Matching a boolean field

Match specs compare values as strings, so a toggle is matched against "true" rather than true:

[
    {
        "type": "toggle",
        "name": "useProxy",
        "label": "Use a proxy"
    },
    {
        "type": "fieldGroup",
        "visible": {
            "useProxy": "true"
        },
        "fields": [
            {
                "type": "text",
                "name": "proxyUrl",
                "label": "Proxy URL"
            }
        ]
    }
]

A checkbox does not expose a value to match against at all. Give it a string value and match that instead:

[
    {
        "type": "checkbox",
        "name": "showAdvanced",
        "label": "Advanced options",
        "value": "show"
    },
    {
        "type": "fieldGroup",
        "visible": {
            "showAdvanced": "show"
        },
        "fields": []
    }
]

UI type definitions

An autocomplete dropdown that allows users to search and select from a predefined list of values. Use fixed values when the available options are known in advance and unlikely to change.

[{
    "type": "autocomplete",
    "name": "region",
    "label": "Region",
    "data": {
        "source": "fixed",
        "values": [
            {
                "value": "us-east-1",
                "label": "US East (N. Virginia)"
            },
            {
                "value": "us-east-2",
                "label": "US East (Ohio)"
            }
        ]
    },
    "allowCustomValues": true
}]

A checkbox input for enabling or disabling a boolean option. Use defaultValue to control whether the checkbox is selected by default.

{
    "type": "checkbox",
    "name": "enabled",
    "label": "Enable feature",
    "defaultValue": true
}

A selectable chip group that allows users to choose from a set of predefined options. Choice chips provide a compact, visual alternative to radio buttons or dropdowns for short lists of values.

{
    "type": "choiceChips",
    "name": "tags",
    "label": "Tags",
    "options": [
        {
            "value": "a",
            "label": "Option A"
        },
        {
            "value": "b",
            "label": "Option B"
        }
    ]
}

A syntax-highlighted Monaco code editor for structured or multi-line content such as JSON payloads, SQL queries, scripts, or request bodies. Use the language property to enable appropriate syntax highlighting and editor behavior.

{
    "type": "code",
    "name": "body",
    "label": "Request Body",
    "language": "json"
}

An expression input for dynamic values or logic-based configuration. Expressions support Mustache variables, allowing values to be injected dynamically at runtime, such as dashboard variables, timeframe values, or parameter inputs.

{
    "type": "expression",
    "name": "filter",
    "label": "Filter Expression"
}

A JSON editor for entering structured configuration data as valid JSON. Use this input when users need to supply complex objects, arrays, or nested configuration values.

{
    "type": "json",
    "name": "config",
    "label": "Configuration"
}

A key-value editor for entering collections of paired values such as HTTP headers, query parameters, environment variables, or metadata. Users can add, edit, and remove entries dynamically.

{
    "type": "key-value",
    "name": "headers",
    "label": "Headers"
}

A read-only Markdown content block for displaying formatted guidance, instructions, warnings, or contextual information within the configuration UI. Supports standard Markdown formatting such as headings, bold text, lists, and links.

{
    "type": "markdown",
    "name": "info",
    "content": "**Note:** Replace the placeholder values below."
}

A numeric input for integer or decimal values such as ports, thresholds, limits, or timeouts. Use defaultValue to provide an initial value when the field is first displayed.

{
    "type": "number",
    "name": "port",
    "label": "Port",
    "defaultValue": 443
}

An object picker that allows users to select one or more indexed objects from the SquaredUp graph. Use it in a data stream’s ui array to let the tile filter the stream down to the objects the user picks.

matches controls which objects are selectable, and is required. It takes a match spec tested against the properties of each indexed object. The property you will reach for most often is sourceType, the object type as the plugin imported it:

{
    "type": "objects",
    "name": "project",
    "label": "Project (optional)",
    "matches": {
        "sourceType": {
            "type": "oneOf",
            "values": [
                "Vercel Project"
            ]
        }
    }
}

To offer every indexed object, use the "all" shorthand:

{
    "type": "objects",
    "name": "scope",
    "label": "Scope",
    "matches": "all"
}

To select objects of more than one type, list them in a single oneOf clause:

{
    "type": "objects",
    "name": "orgUnit",
    "label": "Customer or Site (optional)",
    "objectLimit": 1,
    "matches": {
        "sourceType": {
            "type": "oneOf",
            "values": [
                "Customer",
                "Site"
            ]
        }
    }
}

The remaining properties:

Property
Type
Description
matches
match spec
Which objects are selectable. Required.
objectLimit
number
The maximum number of objects the user may select.
allowVariables
boolean
Allows a dashboard variable to be selected in place of specific objects, so the tile follows the variable.
searchPlaceholder
string
Placeholder text for the picker's search box.
nodeProperties
array of strings
Extra object properties to load with each selection, for use in optionsFormat.
optionsFormat
object
Controls how each option is labeled. Set type to template and supply config.textTemplate, and optionally config.subtextTemplate.
validation
object
Accepts required only.

Selected objects are stored as an array under the field’s name, even when only one is selected, and each object’s rawId is itself a single-element array. Treat an empty or absent value as “no filter applied” so the same data stream can serve both the account-wide and the per-object case.

A secure text input for sensitive values such as API keys, passwords, or tokens. Values entered into a password field are masked in the UI.

{
  "type": "password",
  "name": "apiKey",
  "label": "API Key"
}

A radio button group that allows users to select a single option from a small set of predefined values. Radio buttons are best used when all available options should be visible at once.

{
    "type": "radio",
    "name": "environment",
    "label": "Environment",
    "options": [
        {
            "value": "prod",
            "label": "Production"
        },
        {
            "value": "dev",
            "label": "Development"
        }
    ]
}

A toggle-style selector that allows users to switch between a small set of predefined options. Switch inputs are best suited to simple view or mode changes where only one option can be selected at a time.

{
    "type": "switch",
    "name": "view",
    "label": "View",
    "options": [
        {
            "value": "table",
            "label": "Table"
        },
        {
            "value": "chart",
            "label": "Chart"
        }
    ]
}

A single-line text input for freeform values such as hostnames, IDs, search terms, or query parameters. Use placeholder to provide an example or suggested format for the expected value.

{
    "type": "text",
    "name": "hostname",
    "label": "Hostname",
    "placeholder": "api.example.com"
}

A multi-line text input for longer freeform content such as queries, descriptions, scripts, or notes. Use rows to control the initial visible height of the text area.

{
    "type": "textarea",
    "name": "query",
    "label": "Query",
    "rows": 5
}

A toggle control for enabling or disabling a boolean setting. Toggles are best used for simple on/off configuration options. Use defaultValue to control the initial state of the toggle.

{
    "type": "toggle",
    "name": "advancedMode",
    "label": "Advanced Mode",
    "defaultValue": false
}

Value shapes

Most fields store a single value under their name. Three do not, which matters when you read the value back in a plugin handler or reference it in a configuration.

Type
Stored as
autocomplete
An array of { "value": ... } objects, even when the field is single-select.
key-value
An array of { "key": ..., "value": ... } objects.
objects
An array of objects, where each object's rawId is itself a single-element array.

Examples

The following examples show different use cases for the form elements you can define.

A password field for plugin setup

[
  {
    "type": "password",
    "name": "apiKey",
    "label": "API key",
    "help": "Create an API key in the [provider portal](https://example.com/api-keys)",
    "validation": {
      "required": true
    },
    "placeholder": "e.g. sk_live_xxxxxxxxxxxxxxxx"
  }
]

A text field for data stream config

[
  {
    "name": "domain",
    "type": "text",
    "label": "Domain",
    "placeholder": "mydomain.com",
    "validation": {
      "required": true
    }
  }
]

Mapping field values

The name property of a UI field defines the variable name used when mapping user input into your configuration.

Values entered into the field can then be referenced using Mustache template expressions such as {{apiKey}}.

For example, if your plugin configuration requires an API key, you could create a password field named apiKey. The value entered by the user is then available at runtime through the matching Mustache variable.

{
  "baseUrl": "https://api.example.com/{{apiKey}}",
  "endpointPath": "domain/{{domain}}"
}

[
  {
    "type": "password",
    "name": "apiKey",
    "label": "API Key"
  }
]

Was this article helpful?


Have more questions or facing an issue?