Custom card components (BETA)

APPLICABLE PRODUCTS
  • Sales Hub
    • Enterprise
  • Service Hub
    • Enterprise

Below, learn about the components that you can include in custom cards to extend the CRM record UI.

You can also use the UI extensions playground in your HubSpot account to preview components and copy their code into your project.

To access the UI Extensions Playground, navigate to CRM Development in the main navigation bar, then click UI Extensions Playground in the left side sidebar menu.

ui-extensions-playground

To view example projects that contain fully built custom cards, check out HubSpot's example extension library on GitHub.

Components should be included in the sections array of your serverless function. Standard components can be used by extensions in all locations, while other components can only be used by extensions in the middle pane.

Standard components include:

In addition, extensions in the middle pane can use the following components:

try { sendResponse({ sections: [ { "type": "text", "format": "markdown", "text": "**Markdown**" }, { "type": "button", "text": "Click me", "onClick": { "type": "SERVERLESS_ACTION_HOOK", "serverlessFunction": "crm-card" } }, ], }); } catch (error) { throw new Error(`There was an error fetching the quote': ${error.message}`); }

Below, learn about each type of component and how to include it in an extension.

Standard components

Alert

Renders a single alert.

crm-card-alerts

type  string (required)

The component type. For alerts, use alert.

title  string (required)

The bolded title text of the alert.

body  string or object (required)

The explanatory text that appears below the title. To display plain text, set body to a string value. To use markdown syntax, set body to a text component object.

variant  string

The color of the alert. The following variants are available:

  • info (default)
  • success
  • warning
  • error
// example alert components { "type": "alert", "title": "This is the alert title.", "body": { "type": "text", "format":"markdown", "text": "This is the body text of an `info` alert." }, "variant": "info" }

Button

Renders a single button. Learn more about success and error handling and view examples in HubSpot's extension example library on GitHub.

crm-card-buttons

type  string (required)

The component type. For buttons, use button.

text  string (required)

The button's display text.

href  string 

Navigates to a URL on button click. When a button includes both href and an onClick action, both will be executed on button click. Links to external pages will open in a new tab, while links to pages in the HubSpot account will open in the same tab.

tooltip  string

The text displayed in a tooltip on hover.

onClick  action 

The button's action type.

disabled  boolean

Set to true to render the button in a disabled state.

variant  string 

The type of button to display. The following variants are available:

  • primary
  • secondary (default)
  • destructive
// example button component { "type": "button", "text": "Primary button", "tooltip": "Hover text.", "variant":"primary", "onClick": { "type": "SERVERLESS_ACTION_HOOK", "serverlessFunction": "functionName" } }

Button row

Renders a row of button components. Learn more about success and error handling and view examples in HubSpot's extension example library on GitHub.

crm-card-button-row-component

type  string (required)

The component type. For button rows, use buttonRow.

buttons  array (required)

An array containing button component objects. The same properties are available for buttons when included in a button row.

// example button row component { "type": "buttonRow", "buttons": [ { "type": "button", "variant": "primary", "text": "Action 1" }, { "type": "button", "text": "Action 2" }, { "type": "button", "text": "Action 3" }, { "type": "button", "text": "Action 4" } ] }

Divider

Renders a divider for spacing out components.

crm-card-divider

type  string (required)

The component type. For dividers, use divider.

distance  string

The space between the divider and the content above and below it. Can be set to any of the following:

  • extra-small
  • small
  • medium (default)
  • large
  • extra-large
  • flush
// example divider component { "type": "text", "text": "Plain text above the divider." }, { "type": "divider", "distance": "small" }, { "type": "text", "text": "Plain text below the divider" }

Description list

Renders pairs of labels and values. 

crm-card-description-list

type  string (required)

The component type. For description lists, use descriptionList.

items  array (required)

An array that contains an object for each label and value pair. To display plain text, set body to a string value. To use markdown syntax, set body to a text component object.
direction  string

The direction that the label and value pairs are displayed. By default, the value is set to column. You can also set the direction to row.
// example description list component { "type": "descriptionList", "items": [ { "label": "Dog name", "value": "Oscar" }, { "label": "Birthday", "value": "2/13/2021" }, { "label": "Favorite toy", "value": { "type": "text", "format": "markdown", "text": "[Snake](https://www.hubspot.com/)" } } ] }

Form

Renders a form that can contain other components, such as input and button fields. Using events, you can then trigger serverless functions based on button click.

To see an example of a simple form, check out HubSpot's extension example library on GitHub.

crm-card-input-field

type  string (required)

The component type. For forms, use form.

content  array (required)

An array containing other components that represent the data to display in the form. For example:

input  

An input component that renders a fillable form field with a default value.

button  

A button component that renders a form submit button. On click, the button will execute the exampleFunction serverless function. Form buttons must use the "SUBMIT" action type to enable form submissions.

// example form component { "type": "form", "content": [ { "type": "input", "name": "example_input", "inputType": "text", "label": "Example input field", "initialValue": "This is the default value for this field." }, { "type": "button", "text": "Submit form", "onClick": { "type": "SUBMIT", "serverlessFunction": "exampleFunction" } } ] }

Heading

Renders large heading text, supporting plain text and markdown.

crm-card-heading-text

type  string (required)

The component type. For headings, use heading.

text  string (required)

Text to be displayed. Supports markdown when an additional property of "format": "markdown" is included.

// example heading component { "type": "heading", "text": "Heading text" }, { "type": "heading", "format": "markdown", "text": "*Markdown heading* [text](https://www.hubspot.com)" }

Image

Renders an image.

crm-card-image

type  string (required)

The component type. For images, use image.

src  string (required)

The URL of the image.

alt  string (required)

The image's alt text.

width  number 

Sets a max-width for the image. When resizing, HubSpot will automatically adjust the height to respect the image's original aspect ratio.

Images cannot exceed the width of the extension's container at various screen sizes, and values beyond that maximum width will not be applied to the image.

onClick  object

A card action object that triggers an action on element click.

// example image component { "type":"image", "src":"https://hubspot.com/hubfs/the-sprocket.svg", "alt":"HubSpot logo", "width":100, "onClick": { "type": "SERVERLESS_ACTION_HOOK", "serverlessFunction": "my-custom-function" } }

Input

Renders a text input field where a user can enter a custom text value. Can only be used within a form component. You can retrieve the end user's submitted value with payload.formState.fieldName. For example, to retrieve the value submitted for an input with a name of example_select_input, use payload.formState.example_select_input. Learn more about the form submit action.

crm-card-input-fields

type  string (required)

The component type. For inputs, use input.

name  string (required)

The input's unique identifier, similar to the HTML input element name attribute.

label  string 

The text that displays above the input. Required if inputType is not set to hidden.

tooltip  string 

The text that displays in a tooltip next to the label.

inputType  string

The type of form input to display. Supports the following values:

  • text (default): displays a standard single-line text input field.
  • hidden: the input is not displayed but contains a value that gets passed on form submission.
initialValue  string

The value that the field is initially set to on load.

pattern  string (required)

Defines a regex pattern for validation.

description  string 

Displayed text that describes the field's purpose.

placeholder  string 

Text that appears in the input when no value is set.

validationErrorMessage  string 

The error message to display when the regex pattern defined in pattern isn't matched. This field is required when including pattern.

readonly  boolean 

Sets the field as read-only on the CRM record. Users will not be able to fill the input field when set to true.

required  boolean 

Sets the input as required for the form to be submittable.

requiredValidationMessage  string 

The error message to display when the user hasn't entered a value in a required field.

// example input components { "type": "input", "name": "magicId", "inputType": "hidden", "label": "ID value that references another system", "initialValue": "589fe9fa-a691-4a88-a073-ca8d70d3bc9b" }, { "type": "input", "name": "one", "inputType": "text", "readonly": true, "label": "Input 1" }, { "type": "input", "name": "two", "inputType": "text", "label": "Input 2", "initialValue": "default value", "pattern": "[a-zA-Z0-9 ]{4,10}", "validationErrorMessage": "Value must contain only letters and numbers and be between a 4-10 characters" }

Progress bar

Renders a progress bar that shows a numeric and/or percentage-based representation of progress. HubSpot calculates the percent based on the maximum possible value specified in the component.progress-bar-component

type  string (required)

The component type. For progress bars, use progressBar.

title  string

The text that displays above the progress bar.

showPercentage  boolean 

Whether the progress bar displays the completion percentage.

value  number 

The number representing the progress so far. Defaults to 0.

valueMax  number 

The maximum value of the progress bar. Defaults to 100.

valueDescription  string 

The text that explains the current state of the value property. For example, "150 out of 250". Displays above the progress bar on the right side.

variant  string

The color that indicates the type of progress bar. Can be one of the following:

  • success
  • danger
  • warning
// example progress bar component { "type": "heading", "text": "Products purchased in last month" }, { "type": "progressBar", "variant": "success", "valueMax": 150, "value": 50, "title": "T-shirts", "valueDescription": "50 out of 150", "showPercentage": true }, { "type": "progressBar", "variant": "warning", "valueMax": 100, "value": 20, "title": "Bottles", "valueDescription": "20 out of 100", "showPercentage": true }, { "type": "progressBar", "variant": "danger", "valueMax": 150, "value": 10, "title": "Stickers", "valueDescription": "10 out of 150", "showPercentage": true }

Select input

Renders a dropdown select input field where a user can select a single value. When there are more than seven selectable options in the input, the component will automatically include a search field. Can only be used within a form component. 

You can retrieve the end user's submitted value with payload.formState.fieldName. For example, to retrieve the value submitted in a select input with a name of example_select_input, use payload.formState.example_select_input. Learn more about the form submit action.

select-input-component-search

type  string (required)

The component type. For inputs, use select.

name  string (required)

The input's unique identifier, similar to the HTML input element name attribute.

label  string (required)

The text that displays above the input.

placeholder  string 

Text that appears in the input when no value is selected.

description  string 

Displayed text that describes the field's purpose.

tooltip  string 

The text that displays in a tooltip next to the label.

initialValue  string, boolean, number

The value that the field is initially set to on load. Enables you to pre-fill the field.

validationErrorMessage  string 

The error message that displays if a value is provided for initialValue that doesn't match any of the values in the options array. If no value is provided for this field, a generic error message will display.

options  array (required)

An array of options available in the dropdown select. Each option is an object containing:

  • value: the unique internal value. Can be a string, boolean, or number.
  • label: the label that displays in the field. Must be a string.

When you include more than seven options in this array, a search field will automatically be added to the component.

readonly  boolean 

Sets the field as read-only on the CRM record. Users will not be able to fill the input field when set to true.

required  boolean 

Sets the input as required for the form to be submittable.

requiredValidationMessage  string 

The error message to display when the user hasn't entered a value in a required field.

// example select input component inside a form component { "type": "select", "name": "example_select_input", "label": "Example select input field", "placeholder": "Select an option", "description": "Please select an item from the list", "tooltip": "This is a tooltip.", "options": [ { "value": 1, "label": "Option 1" }, { "value": 2, "label": "Option 2" }, { "value": 3, "label": "Option 3" }, { "value": 4, "label": "Option 4" }, { "value": 5, "label": "Option 5" }, { "value": 6, "label": "Option 6" }, { "value": 7, "label": "Option 7" }, { "value": 8, "label": "Option 8" } ] }

Stack

Renders a vertical stack of other components with adjustable spacing.

crm-card-component-stack

 

type  string (required)

The component type. For stacks, use stack.

content  array (required)

The components to render in the stack.

distance  string

The amount of vertical space between each component in the content array. Can be set to "small" (default) or "flush".

// example stack component { "type": "stack", "distance": "flush", "content": [ { "type": "heading", "text": "Stack example" }, { "type": "text", "format": "markdown", "text": "`stack` can be used to alter the vertical spacing between components." } ] }

Statistics

Renders data summaries.

crm-card-statistics

type  string (required)

The component type. For statistics, use statistic.

items  array (required)

An array of item objects representing each piece of data to display. Each item object can contain the following properties:

  • label
  • number
  • description

Learn more about each property below.

label string (required) 

The statistic's text label.

number string (required) 

The number that displays under the label.

description string or object

Displays helper information under the statistic.

  • To display the description as plain text, enter your text as a string.
  • To instead use markdown syntax, set description to a text component object with "format": "markdown".
  • To display the description as a trend with a directional indicator, set description to an object with the following properties:
    • type: trend
    • value: the statistic value to display.
    • direction: displays an arrow indicating whether the data is trending upwards or downwards. Accepts either increase or decrease.
// example statistics component { "type": "statistics", "items": [ { "label": "Views last week", "number": "55", "description": "Apr 11 - Apr 17" }, { "label": "Views this month", "number": "203", "description": { "type": "trend", "value": "23.36%", "direction": "increase" } }, { "label": "Markdown syntax", "number": "405", "description": { "type": "text", "format": "markdown", "text": "[Feb 12 - Feb 19](https://app.hubspot.com/)" } } ] }

Tag

Renders a tag.

crm-card-tags

type  string (required)

The component type. For tags, use tag.

text  string (required)

The tag's label.

variant  string

The tag's color. The following variants are available: default, warning, success, and error.

onClick  object

A card action object that triggers an action on element click.

// example tag component { "type": "tag", "text": "Tag text", "variant": "default", "onClick": { "type": "SERVERLESS_ACTION_HOOK", "serverlessFunction": "my-custom-function" } }

Text

Renders text, supporting either plain text or markdown.

crm-card-text

type  string (required)

The component type. For text, use text.

format  string

Optionally, you can include format with a value of markdown to render the text with markdown syntax. Learn more about supported syntax below.
text string (required)

The text to display. If format is set to markdown, this property supports the following markdown syntax:

  • Bold:
    • **example**
    • __example__
  • Italics:
    • *example*
    • _example_
  • Inline code: `example`
  • Links: [visible anchor text](https://www.hubspot.com)
variant string

The style of text to display. Can be either of the following values for either plaintext or markdown:

  • bodytext: the default value which renders the standard text size.
  • microcopy: smaller text used for adding context.
// example markdown component { "type": "text", "text": "This is a plaintext string" }, { "type": "text", "format": "markdown", "text": "The word **bold** is bolded, and the word [link](https://www.hubspot.com/) is a link. here's `code` and _italics_ too" }

Text area

In a form, renders a multi-line plain text field. You can retrieve the end user's submitted value with payload.formState.fieldName. For example, to retrieve the value submitted to a field with the name of textarea_field, use payload.formState.textarea_field. Learn more about the form submit action.

Can only be used within a form component. 

text-area-component

type  string (required)

The component type. For text areas, use textarea.

name  string (required)

The text area's unique identifier, similar to the HTML <textarea> element's name attribute.

label  string (required)

The text that displays above the field. 

tooltip  string 

The text that displays in a tooltip next to the label.

initialValue  string

The value that the field is initially set to on load.

description  string 

Displayed text that describes the field's purpose.

placeholder  string 

Text that appears in the field when no value is set.

readonly  boolean 

Sets the field as read-only on the CRM record. Users will not be able to fill the input field when set to true.

required  boolean 

Sets the field as required for the form to be submittable.

requiredValidationMessage  string 

The error message to display when the user hasn't entered a value in a required field.

cols  number 

The visible width of the field in average character widths.

rows  number 

The number of visible text lines in the field.

maxLength  number 

The maximum number of characters (UTF-16 code units) that the user can enter. If this value isn't specified, the user can enter an unlimited number of characters.

resize  vertical, horizontal, both, none 

Sets whether an element is resizable, and if so, in which directions. Possible values include:

  • vertical
  • horizontal
  • both
  • none
// example form with textarea component { "type": "form", "content": [ { "type": "textarea", "name": "example_textarea", "label": "Example textarea field", "initialValue": "This is the default value for this field." }, { "type": "button", "text": "Submit form", "onClick": { "type": "SUBMIT", "serverlessFunction": "exampleFunction" } } ] }

Toggle group

In a form, renders a group of checkboxes or radio button subcomponents. You can retrieve the end user's submitted value with payload.formState.fieldName. For example, to retrieve the value submitted for a checkbox with a name of checkbox1, use payload.formState.checkbox1. Learn more about the form submit action.

Can only be used within a form component. 

toggle-group-component

type  string (required)

The component type. For toggle groups, use toggleGroup.

name  string (required)

The toggle group's unique identifier.

label  string (required)

The text that displays above the toggle group. 

toggleType  checkboxList, radioButtonList (required)

The type of toggle group to render (checkboxes or radio buttons).

tooltip  string 

The text that displays in a tooltip next to the group.

required  boolean 

When set to true, the toggle group will be required for the form to be submittable.

requiredValidationMessage  string 

The error message to display when the user hasn't entered a value in a required field.

inline  boolean 

When set to true, the checkboxes or radio buttons will render horizontally.

variant  default, small 

The size of the checkboxes or radio buttons to display. Defaults to default.

options array

The list of checkboxes or radio buttons to display. The array will contain the following properties:

label string (required) 

The checkbox or radio button text label.

value string (required) 

The checkbox or radio button's value. 

initialIsChecked boolean 

Whether the checkbox or radio button is selected by default. If this is set to true for multiple radio buttons, only the last one in the list will be checked by default.

readonly boolean 

When set to true, the user will not be able to select the checkbox or radio button.

description string 

Displayed text that describes the checkbox or radio button's purpose.

// example form with a checkbox-type toggle group component { "type": "form", "content": [ { "type": "toggleGroup", "toggleType": "checkboxList", "name": "checkbox_input", "label": "Select all that Apply", "options": [ { "value": "42", "label": "Option 1" }, { "value": "cake", "label": "Option 2" }, { "value": "a string", "label": "Option 3" } ] }, { "type": "button", "text": "Submit form", "onClick": { "type": "SUBMIT", "serverlessFunction": "exampleFunction" } } ] }

Tile

Renders a square tile containing other components.

crm-card-tile

type  string (required)

The component type. For tiles, use tile.

body  array (required)

An array containing other CRM card component objects.

// example tile component { "type": "tile", "body": [ { "type": "text", "text": "Some Important content" }, { "type": "text", "format": "markdown", "text": "some **very** _related_ content with a [link](https://www.hubspot.com/)" } ] }

Middle pane components

Property list

Built on top of the description list component, this component enables you to display a read-only list of property values from a specified CRM record. This component enables you to access property data from specific records without needing to configure propertiesToSend.

Available for cards in the middle pane only.

Please note: record IDs are unique to each account. If you're developing in multiple accounts, including sandbox accounts, you'll need to update the component to use IDs that are specific to each account. 

crm-propertylist-component

type  string (required)

The component type. For this component, use crm::propertyList.

objectTypeId  string (required)

The type of object you're pulling data from (i.e., contacts for contacts).

When referencing a custom object, use the format p_objectName where objectName matches the custom object's name value exactly.

objectId  string (required)

The ID of the specified CRM record to display properties from.

properties  array (required)

The internal names of the properties to display.

direction  string

The direction that the properties will display in. By default, direction is set to "column". Set to "row" to display properties in rows.

// example crm::propertyList component { "type": "crm::propertyList", "objectTypeId": "contacts", "objectId": "9451", "properties": ["firstname", "lastname", "company"] }

Table

Displays a table of CRM data for a specified object, including custom objects. Specified properties will display as columns, with records filling out rows. This component enables you to access property data from records without needing to configure propertiesToSend.

Available for extensions in the middle pane only.

crm-table-component

type  string (required)

The component type. For this component, use crm::table.

objectTypeId  string (required)

The type of object you're pulling data from (i.e., contacts for contacts).

When referencing a custom object, use the format p_objectName where objectName matches the custom object's name value exactly.

properties  array (required)

Contains the properties to display as table columns.

pageSize  string

Maximum number of rows to shower per page. Defaults to 10.

// example crm::table component { "type": "crm::table", "objectTypeId": "contacts", "properties": [ "email", "hubspot_owner_id", "firstname", "lastname" ], "pageSize": 3 }

Was this article helpful?
This form is used for documentation feedback only. Learn how to get help with HubSpot.