Create UI extensions with React (BETA)

After creating a project and a public app or private app within it, you can create a UI extension to customize and extend HubSpot's CRM record and help desk UI. In this guide, you'll learn how UI extensions work and how to build them. To learn more about configuring UI extensions, check out the UI extensions SDK reference.

You can also follow the quickstart guide to build and deploy an example UI extension to your account. Or, check out HubSpot's other sample projects.

In this guide:

Prerequisites

Before getting started, ensure you've also set up the following:

If you haven't created a UI extension before, you may want to start with the private app or public app quickstart guide or view HubSpot's example UI extensions.

Set up extension files

Within your project's app directory, create an /extensions directory with the following files:

  • example-card.json: the card configuration.
  • Example.jsx: the React file that serves as the front-end. 
  • package.json: metadata about the extension's front-end. This file is required and can be used to include dependencies for your React front-end.

In the extensions directory, you'll also need to install the HubSpot UI extensions npm package by running npm i @hubspot/ui-extensions.

example-card.json

The configuration file for the UI extension's app card.

// Example extension config file { "type": "crm-card", "data": { "title": "Example Card", "location": "crm.record.tab", "uid": "unique-extension-name", "module": { "file": "Example.jsx" }, "objectTypes": [{ "name": "contacts" }] } }
Use this table to describe parameters / fields
FieldTypeDescription
type
String

The type of extension. Must be crm-card.

title
String

The name of the card.

location
Stringlocation (string): where the card appears in HubSpot's UI. Learn more about extension location.
  • crm.record.tab: places the card on a tab of the middle pane of CRM records.
  • crm.record.sidebar: places the card in the right sidebar of CRM records.
  • crm.preview: places the card in the right side preview panel that you can access from record pages, index pages, board views, and lists pages.
  • helpdesk.sidebar: places the card in the ticket sidebars within help desk. This includes the ticket preview panel on the help desk home page and the right sidebar of the ticket view in help desk. This location is separate from the ticket CRM record page.
uid
StringThe extension's unique identifier. This can be any string, but should meaningfully identify the extension. HubSpot will identify the extension by this ID so that you can change the extension's title without removing historical or stateful data, such as the card's position on the CRM record.
module
ObjectAn object containing the file field, which contains the the location of the app card's font end React code. 
objectTypes
Array

Defines which types of CRM object records the extension will appear on. This will also enable you to pull data from those records when using the fetchCrmObjectProperties method. Learn more about compatible objects.

Extension location

You can configure which part of the HubSpot UI to customize using the location property in the extension's JSON config file. The follow locations are available:

  • crm.record.tab: places the extension in the middle column of CRM record pages, either in one of HubSpot's default tabs or in a custom tab. If you've customized the middle column previously, you'll need to customize the middle column view to make any newly created extensions visible.
    middle-column-example-card
  • crm.record.sidebar: places the extension in the right sidebar of CRM record pages. Extensions in the sidebar cannot use CRM data components.
right-sidebar-example-card
  • crm.preview: places the app card in the preview panel that you can access throughout the CRM. When using this location, the extension will be available when previewing the objectTypes specified in the JSON config file. This includes previewing records from within CRM record pages, index pages, board views, and the lists tool. Learn more about customizing previews.
    preview-example-card
  • helpdesk.sidebar: places the card in the ticket sidebars within help desk. This includes both the ticket preview panel on the help desk home page and the right sidebar of the ticket view in help desk. To add a card to this location, you'll need to configure your help desk settings to include the card. 
Please note: when creating an extension for this location, you'll also need to ensure that the app's JSON configuration file includes tickets in the scopes array, and that the card's JSON configuration file includes tickets in the objectTypes field.

Help desk home page:

help-desk-uie-example-home-page-preview

Help desk ticket view:

help-desk-uie-example-ticket-page

Compatible objects

You can create extensions for both standard object and custom object records. In the app card's JSON configuration file, you'll define this within the objectTypes array. 

When building an extension for custom objects, you'll reference the object as p_objectName (case sensitive). To get this value, make a GET request to the custom object schema API, then look for the fullyQualifiedName in the response. Take the fullyQualifiedName, then remove the HubID number, and use the resulting value for the configuration file.

// example card.json "objectTypes": [ { "name": "p_Cats" } ]

For example, for a custom object with the fullyQualifiedName of p123456_Cats, the correct value to use for the configuration file would be p_Cats.

Example.jsx

The React front-end file. Note that this example code is for a UI extension powered by a private app, as it includes a serverless function. For a public app, you would not include a serverless function. Instead, you would provide your own custom back-end.

// Example React front-end import React, { useState } from 'react'; import { Button, Text, Input, Stack, hubspot, } from '@hubspot/ui-extensions'; hubspot.extend(({ context, runServerlessFunction, actions }) => ( <Extension context={context} // runServerlessFunction is for private apps only runServerless={runServerlessFunction} sendAlert={actions.addAlert} /> )); const Extension = ({ context, runServerless, sendAlert }) => { const [text, setText] = useState(''); const run = () => { runServerless({ name: 'myFunc', parameters: { text: text } }).then((resp) => sendAlert({ message: resp.response }) ); }; return ( <> <Text> <Text format={{ fontWeight: 'bold' }}> Your first UI Extension is ready! </Text> Congratulations {context.user.firstName}! You just deployed your first HubSpot UI extension. This example demonstrates how you would send parameters from your React front-end to the serverless function and get response back. </Text> <Stack> <Input name="text" label="Send to serverless" onInput={(t) => setText(t)} /> <Button type="submit" onClick={run}> Click me </Button> </Stack> </> ); };

package.json

Metadata about the extension's front-end. This file is required and can be used to include dependencies for your React front-end.

// Example package.json { "name": "example-extension", "version": "0.1.0", "description": "", "license": "MIT", "main": "Example.jsx", "scripts": { "dev": "hs-ui-extensions-dev-server dev", "build": "hs-ui-extensions-dev-server build" }, "repository": { "type": "git", "url": "https://github.com/HubSpot/ui-extensions-react-examples" }, "dependencies": { "@hubspot/ui-extensions": "latest", "react": "^18.2.0" } }

Start local development

With your project files created locally, you can now run hs project dev to upload the files to HubSpot, then run hs project dev to start a local development server. start a local development server to view the extension in HubSpot. The local development server will pick up changes saved to your React files without needing to refresh the page or re-upload the project. 

Learn more about local development for UI extensions.

hs project dev

Adding cards to the UI

To view an app card in HubSpot, you'll need to add it to the UI in its specified location. For example, to add a card to the contact record view:

  • Log in to your HubSpot account.
  • In your HubSpot account, navigate to ContactsContacts. Then, click the name of a contact to view its record.
  • At the top of the contact record, click Customize tabs. A new tab will open showing the record editor sidebar.
    crm-recrd-customize-tabs
  • In the right sidebar, click Default view to edit the default contact record view.
  • For the purposes of this tutorial, click the + plus icon tab at the top of the editor to add a new tab.
    crm-record-page-editor-add-tab
  • In the dialog box, enter a name for your new tab, then click Done.
  • With the new tab added, click the Add cards dropdown menu.
  • In the right panel, under Card types, click Apps.
    add-app-card-to-middle-column-hello-public-ap
  • Select the checkbox next to the example extension that's part of your public app.
  • Click the X at the top of the right panel to close it.
  • In the top right, click Save and exit.
  • Navigate back to the contact record, then refresh the page. You should now see your new tab, which will contain your new card. With the local development server running, you'll see a Developing locally tag displayed at the top of the card.

ui-ext-card-quickstart-resultLearn more about configuring UI extensions using the UI extensions SDK.


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