Skip to main content

Custom Card UI Configs

The Configurations domain can be used to define custom UI config fields that appear on the Card (Activity Plan Template) edit form. This allows you to extend the card settings beyond the built-in options (like Persistent, Dismissible, Card Layout, etc.) without any code changes.

Custom fields appear below a divider in the Ui Configs section of the Card form, beneath the standard built-in fields.


How It Works

  1. You create a Configuration with a specific Path
  2. The Value contains a JSON definition of your custom fields
  3. The portal reads this Configuration and dynamically renders the fields in the Card edit form
  4. When a coach saves the Card, the custom values are stored in the card's uiConfigs object alongside the built-in fields
  5. The mobile app can then read these values to alter how it renders the card

Step 1: Create the Configuration

Navigate to Configurations and create a new item with the following settings:

FieldValue
NameA descriptive name, e.g. Custom Card Theme
PathuiConfigs.activityPlanTemplate.custom
ReadableOn
WriteableOn
info

The Path must be exactly uiConfigs.activityPlanTemplate.custom. This is the path the portal uses to look up custom card UI config definitions. All custom card fields must be defined under this path.

Step 2: Define Fields in the Value

The Value field must contain a JSON object with a name and a fields array. Each entry in fields defines a single form input.

Here is the general structure:

{
"name": "My Custom Config",
"fields": [
{
"type": "TEXT",
"path": "uiConfigs.",
"key": "MY_CUSTOM_FIELD"
}
]
}

Each field object supports the following properties:

PropertyRequiredDescription
typeYesThe input type. One of: BOOLEAN, TEXT, NUMBER, SELECT, PLACEHOLDER
pathYesThe storage path prefix. Use uiConfigs. so the value is stored in the card's uiConfigs object
keyYesThe field key in MACRO_CASE (e.g. CARD_THEME). This becomes the key in uiConfigs
labelNoA custom display label for the field. If omitted, the key is converted to title case (e.g. CARD_THEMECard Theme)
defaultValueNoThe default value when the field is empty. If omitted, the field starts blank
requiredNoSet to true to make the field mandatory
disabledNoSet to true to make the field read-only
choicesNoRequired for SELECT type. Array of { "value": "...", "label": "..." } objects
conditionNoShow this field only when another field matches specific values (see Conditional Fields below)
placeholderSizeNoFor PLACEHOLDER type only. Grid column width (1-12) for layout spacing
tip

By default, the key is automatically converted to a human-readable label in the form. For example, CARD_THEME becomes Card Theme. You can override this by setting the label property to any custom text (e.g. "label": "Reading Time").


Step 3: Choose the Right Field Type

BOOLEAN

A toggle switch for true/false values.

{
"type": "BOOLEAN",
"path": "uiConfigs.",
"key": "SHOW_PROGRESS_BAR",
"defaultValue": "true"
}

TEXT

A free-text input field.

{
"type": "TEXT",
"path": "uiConfigs.",
"key": "CUSTOM_HEADER_TEXT",
"defaultValue": "Welcome",
"required": true
}

NUMBER

A numeric input field.

{
"type": "NUMBER",
"path": "uiConfigs.",
"key": "ANIMATION_DURATION_MS",
"defaultValue": "300"
}

SELECT

A dropdown with predefined choices.

{
"type": "SELECT",
"path": "uiConfigs.",
"key": "CARD_THEME",
"defaultValue": "light",
"choices": [
{ "value": "light", "label": "Light" },
{ "value": "dark", "label": "Dark" },
{ "value": "system", "label": "System Default" }
]
}

PLACEHOLDER

Not a real input - used for layout spacing in the form grid.

{
"type": "PLACEHOLDER",
"path": "uiConfigs.",
"key": "SPACER",
"placeholderSize": 6
}

Conditional Fields

You can make a field visible only when another field has a specific value. This is useful for showing options that only apply in certain contexts.

Add a condition object with:

  • key - the key of the field to check
  • values - an array of values that make this field visible
{
"name": "Theme Settings",
"fields": [
{
"type": "SELECT",
"path": "uiConfigs.",
"key": "CARD_THEME",
"defaultValue": "light",
"choices": [
{ "value": "light", "label": "Light" },
{ "value": "dark", "label": "Dark" },
{ "value": "custom", "label": "Custom" }
]
},
{
"type": "TEXT",
"path": "uiConfigs.",
"key": "CUSTOM_PRIMARY_COLOR",
"defaultValue": "#000000",
"condition": { "key": "CARD_THEME", "values": ["custom"] }
},
{
"type": "TEXT",
"path": "uiConfigs.",
"key": "CUSTOM_BACKGROUND_COLOR",
"defaultValue": "#FFFFFF",
"condition": { "key": "CARD_THEME", "values": ["custom"] }
}
]
}

In this example, the two color fields only appear when Card Theme is set to "Custom".


Full Example

Here is a complete Configuration Value that adds theme, layout, and behavioral customizations to cards:

{
"name": "Custom Card Behaviors",
"fields": [
{
"type": "SELECT",
"path": "uiConfigs.",
"key": "CARD_THEME",
"defaultValue": "light",
"choices": [
{ "value": "light", "label": "Light" },
{ "value": "dark", "label": "Dark" }
]
},
{
"type": "BOOLEAN",
"path": "uiConfigs.",
"key": "SHOW_PROGRESS_BAR",
"defaultValue": "true"
},
{
"type": "NUMBER",
"path": "uiConfigs.",
"key": "AUTO_ADVANCE_DELAY_MS",
"defaultValue": "0"
},
{
"type": "TEXT",
"path": "uiConfigs.",
"key": "COMPLETION_MESSAGE",
"defaultValue": "Well done!"
}
]
}

This would render four additional fields in the Ui Configs section of every Card form: a theme dropdown, a progress bar toggle, an auto-advance delay input, and a completion message text field.


How Custom Fields Are Stored

When a coach saves a card, the custom field values are merged into the card's uiConfigs object. For the example above, the stored data would look like:

{
"IS_PERSISTENT": false,
"IS_DISMISSIBLE": true,
"CARD_LAYOUT": "STANDARD",
"CARD_THEME": "dark",
"SHOW_PROGRESS_BAR": true,
"AUTO_ADVANCE_DELAY_MS": 500,
"COMPLETION_MESSAGE": "Well done!"
}

The built-in fields and custom fields live side-by-side in the same object. The mobile app reads from this object to determine how to render the card.

warning

Custom field keys must not conflict with built-in keys (IS_PERSISTENT, IS_DISMISSIBLE, CARD_LAYOUT, IMAGE_ASPECT_RATIO, CARD_LAYOUT_TYPE, CARD_CONTENT_TYPE, START_BUTTON_LABEL, NEXT_BUTTON_LABEL, END_BUTTON_LABEL, RESPONSE_UI_CONFIGS). Using a conflicting key will cause unpredictable behavior.