Skip to content

Widget Definition Reference ​

This page documents every field of a widget entry in the widgets array of extensions_registry.json. For the root of the registry file, see Registry Reference.

Working example

The template repository contains a complete extensions_registry.json with example widgets, a global script, and a stylesheet — a useful reference alongside this documentation.

Widget Object ​

FieldTypeRequiredDefaultDescription
titlestringYes—Display name shown to users
typestringYes—Unique widget identifier — must be unique across your community
categorystringYes—Free-form category label, e.g. "engagement", "analytics"
contentobjectConditional—External hosting — see Content Object. Required if source is not set.
sourceobjectConditional—Repository hosting — see Source Block. Required if content is not set.
versionstringNo"1.0.0"Widget version following semver
descriptionstringNo""Brief description of the widget
containersarray of stringsNo["Full width"]Page zones where the widget can be placed. Values: "Full width", "Left container", "Sidebar"
widgetsLibrarybooleanNotrueWhen true, the widget appears in the No-Code Builder library
imageNamestringNo"banner"Built-in thumbnail identifier — see Thumbnails. Ignored when imageSrc is set.
imageSrcstringNo—Custom thumbnail — absolute URL or relative repository path. See Thumbnails. Mutually exclusive with imageName.
settingsobjectNoshared false, container false, others trueWidget behavior settings — see Settings Object
configurationobjectNo—Form fields for the No-Code Builder — see Configuration Object
defaultConfigobjectNo—Default values for configuration properties

XOR Requirement: Each widget must have exactly one of content or source — never both, never neither.

Important: The type field is the widget's unique identifier. Use a descriptive, namespaced format like mycompany_welcome_banner to avoid conflicts with other widgets.

Settings Object ​

FieldTypeRequiredDefaultDescription
configurablebooleanNotrueWhether users can configure the widget after adding it
editablebooleanNotrueWhether the widget content can be edited
removablebooleanNotrueWhether users can remove the widget from pages
sharedbooleanNofalseWhen true, one widget instance is shared across every page it appears on — edits propagate everywhere. Opt in explicitly; the default keeps the widget local to each page.
movablebooleanNotrueWhether users can reposition the widget
containerbooleanNofalseWhether the widget acts as a container for other widgets

An empty settings: {} object is valid — all fields take their defaults.

Content Object ​

FieldTypeRequiredDefaultDescription
endpointstringYes—Public URL to widget content, must start with https://
methodstringNo"GET"HTTP method — "GET" or "POST"
cacheStrategystringNo—Caching behavior — "none", "no-cache", "ttl", or "permanent"
cacheTtlSecondsintegerNo—Cache duration in seconds — use with cacheStrategy: "ttl"
requiresAuthenticationbooleanNofalseNot supported — leave false or omit
headersobjectNo—Optional headers sent with the request
bodyobjectNo—Optional request body, for POST. This declarative body is the platform-side request body for content fetches — distinct from the SDK connectors.execute({ payload }) client option. See the Connectors SDK Reference.
paramsobjectNo—Optional query parameters

Source Block ​

FieldTypeRequiredDefaultDescription
pathstringYes—Directory path relative to repository root
entrystringYes—HTML entry point file relative to path

Configuration Object ​

FieldTypeRequiredDefaultDescription
propertiesarray of objectsYes—Form fields — see ConfigField Object
sectionsarray of objectsNo—Groups that organize fields into collapsible sections — see ConfigSection Object

ConfigField Object ​

FieldTypeRequiredDefaultDescription
namestringYes—Field identifier, used as the configuration key
labelstringYes—Field label shown in the No-Code Builder
typestringYes—Field type — "text", "number", "color", "date", "boolean", "select", or "autocomplete"
descriptionstringNo—Help text shown under the field
sectionstringNo—name of the section this field is grouped under. Presentation only — values are always stored flat, keyed by name. Fields without a section fall into the default group.
defaultValueanyNo—Pre-filled value
rulesobjectNo—Validation rules — see FieldRules Object
optionsarrayNo—Static choices for "select" — see SelectOption Object. Mutually exclusive with dynamicOptions.
dynamicOptionsobjectNo—API-driven choices for "select" or "autocomplete" — see Dynamic Options. Mutually exclusive with options.
multiplebooleanNofalseAllow selecting more than one value. Only for "select" or "autocomplete".
sortablebooleanNofalseLet editors reorder selected values. Only valid for "autocomplete" fields with multiple: true; array order is preserved at runtime.
visibleWhenarray of objectsNo—Rules that decide whether this field is shown, based on other fields' values — see Conditional Visibility.
Field Types ​
typeRenders asNotes
textSingle-line text input—
numberNumeric inputRespects rules.minimum / rules.maximum
colorColor picker—
dateDate picker—
booleanOn/off toggle—
selectDropdownRequires options OR dynamicOptions (see Dynamic Options), not both
autocompleteSearchable fieldRequires dynamicOptions; supports multiple and sortable
FieldRules Object ​
FieldTypeRequiredDefaultDescription
requiredbooleanNo—Whether the field must be filled in
minLengthintegerNo—Minimum string length
maxLengthintegerNo—Maximum string length
patternstringNo—Regex the value must match
minimumnumberNo—Minimum numeric value
maximumnumberNo—Maximum numeric value
SelectOption Object ​
FieldTypeRequiredDefaultDescription
valuestringYes—Value stored when the option is selected
labelstringYes—Label shown in the dropdown

ConfigSection Object ​

An entry in the sections array. A field joins a section by setting its section to the section's name. Listing a section here is optional — it sets the section's label, description, and default-open state.

FieldTypeRequiredDefaultDescription
namestringYes—Section identifier, referenced by a field's section
labelstringNonameTitle shown on the section header
descriptionstringNo—Help text shown under the section header
expandedbooleanNofalseWhen true, this section is the one open when the form first loads
visibleWhenarray of objectsNo—Rules that decide whether the whole section is shown — see Conditional Visibility.
Section Ordering and Rendering ​
  • A section renders only when at least one field references it. A section listed in sections with no fields is not shown.
  • Fields without a section fall into a default group, labeled Configuration, shown first.
  • After the default group, sections appear in the order they are listed in sections, followed by any sections referenced only by a field — those in the order their first field appears.
  • The form shows one section open at a time. On load, the first sections entry marked expanded is opened; if none is marked, the first section is opened.
  • A field's section is presentation only. Configuration values are always stored flat, keyed by field name, so you can rename, reorder, or remove sections without affecting saved values.

Conditional Visibility ​

A config field or section can declare visibleWhen: a list of rules evaluated against the values the editor has entered so far. All rules must pass for the field or section to be shown (AND). An absent or empty list means always visible.

jsonc
{
  "name": "maxCourses",
  "type": "number",
  "label": "Maximum courses shown",
  "visibleWhen": [{ "field": "courseSelection", "operator": "eq", "value": "recent" }]
}

VisibilityRule Object ​

FieldTypeRequiredDefaultDescription
fieldstringYes—name of another config field in the same widget
operatorstringYes—See the operator table below
valuestring, number, boolean, or arrayConditional—Required for every operator except empty and not_empty, which must not declare one

Operators ​

OperatorValid onMeaning
eq / neqtext, color, number, date, boolean, single-value select/autocompleteScalar comparison
in / not_inthe above, plus multi-value fieldsScalar field: the value is one of the listed values. Multi-value field: the selection intersects the list.
contains / not_containsmulti-value select/autocompleteThe selection includes this value
empty / not_emptyeverything except booleanWhether the field has been filled in. Takes no value.
gt / gte / lt / ltenumber, dateThreshold. value is a number or an ISO date.
starts_with / ends_with / includestext, colorCase-insensitive substring checks

There is no regex operator. Use rules.pattern when you need a pattern — that validates a value the editor has entered, which is a different job from deciding what to show.

select and autocomplete fields compare on the stored option value, never the label shown in the dropdown.

Boolean fields use a real JSON boolean — "value": true, not "value": "true".

What Counts as Empty ​

empty is true for a field that is missing, null, an empty string, an empty list, or a selection with no value. It is not true for false, 0, or "0" — those are values an editor deliberately set. This is why not_empty is not allowed on a boolean field: a checkbox always has a value. Use eq with true or false instead.

Behavior ​

  • Values are kept. Hiding a field does not clear it. Configuration values are always stored flat, keyed by field name, so switching a condition back restores what the editor had entered. Your widget receives the full configuration and decides what to read.
  • Hidden fields skip validation. A required field that is not on screen will not block the editor from saving.
  • Options load when shown. A field using dynamicOptions fetches its options the first time it becomes visible, so a hidden branch costs no API calls.
  • Sections follow their fields. A section is hidden when its own visibleWhen fails, and also when every field inside it is hidden. If the open section is the one that just got hidden, the form opens the first section still showing.

Errors Caught at Publish Time ​

The configuration form leaves a field visible when it cannot apply a rule, so a broken rule would otherwise do nothing at all, without warning. Publishing therefore fails when a rule:

  • references a field that is not declared in the same widget, or references its own field
  • uses an operator the target field's type does not support (eq on a multi-value field, contains on a single-value field, gt on a text field, not_empty on a boolean)
  • omits value, or supplies one for empty / not_empty
  • passes a list to an operator that compares a single value
  • compares a boolean field against a string, or a number field against a non-number

Dynamic Options ​

The dynamicOptions object populates a select or autocomplete field's choices from an external API instead of a static options list.

dynamicOptions Object ​

FieldTypeRequiredDescription
endpointobjectYesAPI endpoint to fetch the list of options — see API Endpoint Object
valuesEndpointobjectNoAPI endpoint to resolve stored IDs back to fresh labels — see API Endpoint Object
mappingobjectYesHow to extract value and label from the API response — see Options Mapping Object
isAsyncSearchbooleanNoWhen true, the API is called on every keystroke. Only valid on autocomplete fields.

API Endpoint Object ​

Naming

The field on dynamicOptions is also named endpoint — the URL string lives one level deeper inside it: dynamicOptions.endpoint.endpoint.

Used for both endpoint and valuesEndpoint.

FieldTypeRequiredDescription
endpointstringYesHTTPS URL for the API call. Supports URL template tokens. Must start with https://.
methodstringYesHTTP method — "GET" or "POST"
headersobjectNoAdditional HTTP headers. See Disallowed Headers.
bodyobjectNoRequest body, for POST requests. This declarative body is the platform-side request body for dynamic-options fetches — distinct from the SDK connectors.execute({ payload }) client option. See the Connectors SDK Reference.
paramsobjectNoQuery parameters appended to the URL after template interpolation.

URL Template Tokens ​

Embed these tokens in endpoint URLs to make requests dynamic:

TokenReplaced withUsed in
{q}Current search query (URL-encoded)endpoint on autocomplete fields with isAsyncSearch: true
{value}Stored IDs, comma-joined; each ID is individually URL-encodedvaluesEndpoint

Example: "https://api.example.com/courses?q={q}" sends the current search term as a query parameter.

Disallowed Headers ​

The following headers cannot be declared in headers (case-insensitive): Authorization, Cookie, Set-Cookie, Proxy-*, X-Forwarded-*. The registry is not the right place to store credentials — use a Connector for authenticated external API calls.

params Serialization ​

Entries in params are appended to the URL as a query string after template interpolation:

  • Strings, numbers, and booleans are converted to strings.
  • Arrays become repeated entries: tag=a&tag=b.
  • Objects are JSON-stringified.
  • null and undefined values are skipped.

Example: { "page": 1, "tag": ["a", "b"] } → ?page=1&tag=a&tag=b

Options Mapping Object ​

Maps an API response array to { value, label } pairs.

FieldTypeRequiredDescription
pathstringNoDot-path to the array within the response (e.g. "data.items"). Defaults to the response root.
valueKeystringYesProperty name to use as the stored value (e.g. "id").
labelKeystringYesProperty name to use as the display label (e.g. "name").

path accepts dot-paths like "data.items". A leading $. is stripped for JSONPath compatibility; filters and wildcards are not supported.

Content Endpoint Wire Format ​

When the platform forwards saved widget configuration to your content endpoint, dynamic selection values are normalized:

Saved shapeSent as (GET)Sent as (POST)
Single value?field=id{"field": "id"}
Multiple values?field=id1,id2{"field": ["id1", "id2"]}
Empty selection?field={"field": []}

The cachedLabel is never sent to the content endpoint. If your widget needs a display name, fetch it from your API using the ID.

For a field with multiple: true and sortable: true, the multiple-value order matches the order chosen in the No-Code Builder. The same ordered array is available through sdk.getProps().

Limitations ​

  • Authentication — dynamicOptions endpoints must be publicly accessible. Per-request auth headers are not supported; use a Connector for endpoints that require credentials.
  • Caching — the platform does not cache dynamicOptions responses. For large datasets, prefer isAsyncSearch: true to limit the volume of results returned.
  • Pagination — not supported. Your endpoint should return a usable page size or all items for bounded lists.
  • Cascading fields — one field's selection cannot drive another field's endpoint. Each field's endpoint is fixed at registration time.
  • Response shape — only flat dot-paths and valueKey/labelKey lookups are supported. Filters, computed fields, and wildcard paths are not.

Thumbnails ​

A thumbnail is the preview image shown for a widget in the No-Code Builder library. You have three ways to set one, controlled by two fields on the widget object:

  • Built-in — set imageName to one of the built-in identifiers.
  • External URL — set imageSrc to a publicly accessible image URL.
  • Repository-hosted — set imageSrc to a relative path to an image file in your repository.

imageName and imageSrc are mutually exclusive — if both are set, imageSrc wins. If neither is set, the default imageName: "banner" applies.

Custom thumbnails (external or repository-hosted) must be 512 KB or smaller. For best display, use 420×145 pixels — dimensions are not enforced.

Built-in (imageName) ​

Set imageName to one of the identifiers below. Each preview shows the thumbnail at a reduced size.

imageNamePreview
announcement_cardannouncement_card
autopilotautopilot
autopilot_theloopsautopilot_theloops
badgesbadges
bannerbanner
categoriescategories
community_statisticscommunity_statistics
container-2.1container-2.1
create_ideacreate_idea
customer_education_widgetcustomer_education_widget
dynamic_contentdynamic_content
events_calendarevents_calendar
featured_topicsfeatured_topics
groupsgroups
hero_bannerhero_banner
html_widgethtml_widget
ideation_pipelineideation_pipeline
introduction_barintroduction_bar
leaderboardleaderboard
most_likedmost_liked
quicklinksquicklinks
recommendationsrecommendations
solved_topicssolved_topics
statisticsstatistics
tabstabs
tag_cloudtag_cloud

Example: "imageName": "banner" uses the built-in banner thumbnail.

External URL (imageSrc) ​

Point to any publicly accessible HTTPS image:

json
"imageSrc": "https://example.com/images/my-widget-preview.png"

Repository-hosted (imageSrc) ​

Store the image in your repository and reference it with a relative path from the repo root:

json
"imageSrc": "./images/preview.png"

Both ./images/preview.png and images/preview.png are valid. During publishing, the platform fetches the image from your repository, publishes it, and rewrites the path to an absolute URL. The resulting registry always contains absolute URLs.

Path rules:

  • No path traversal (../ is not allowed)
  • No absolute paths (must not start with /)
  • The image must exist in the repository at the referenced path

Validation Rules ​

The schema enforces these rules:

  1. Root object must have a widgets property (required)
  2. widgets must be an array (may be empty)
  3. Each widget must include all required fields
  4. attributes on scripts and stylesheets must be an object with string values

Validation errors

For a full list of validation and build errors, including causes and fixes, see Error Codes.

Best Practices ​

  1. Use globally unique type values: The type is the widget ID and must be unique across your entire community. Use a prefix like your company or project name (e.g., acme_welcome_banner)
  2. Keep descriptions concise: Brief but descriptive
  3. Set widgetsLibrary: true to make widgets appear in the No-Code Builder library
  4. Use semantic versioning: Follow semver (major.minor.patch)
  5. Validate before pushing: Use a JSON validator to catch syntax errors

Next Steps ​

Gainsight CC Developer Portal