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
- You create a Configuration with a specific Path
- The Value contains a JSON definition of your custom fields
- The portal reads this Configuration and dynamically renders the fields in the Card edit form
- When a coach saves the Card, the custom values are stored in the card's
uiConfigsobject alongside the built-in fields - 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:
| Field | Value |
|---|---|
| Name | A descriptive name, e.g. Custom Card Theme |
| Path | uiConfigs.activityPlanTemplate.custom |
| Readable | On |
| Writeable | On |
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:
| Property | Required | Description |
|---|---|---|
type | Yes | The input type. One of: BOOLEAN, TEXT, NUMBER, SELECT, PLACEHOLDER |
path | Yes | The storage path prefix. Use uiConfigs. so the value is stored in the card's uiConfigs object |
key | Yes | The field key in MACRO_CASE (e.g. CARD_THEME). This becomes the key in uiConfigs |
label | No | A custom display label for the field. If omitted, the key is converted to title case (e.g. CARD_THEME → Card Theme) |
defaultValue | No | The default value when the field is empty. If omitted, the field starts blank |
required | No | Set to true to make the field mandatory |
disabled | No | Set to true to make the field read-only |
choices | No | Required for SELECT type. Array of { "value": "...", "label": "..." } objects |
condition | No | Show this field only when another field matches specific values (see Conditional Fields below) |
placeholderSize | No | For PLACEHOLDER type only. Grid column width (1-12) for layout spacing |
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 checkvalues- 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.
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.