Convert a JSON-based card to a full-stack UI extension (BETA)
-
Sales Hub
- Enterprise
-
Service Hub
- Enterprise
By March 31, 2024, JSON-based cards will no longer be supported and you will not be able to update them. If you're currently still using JSON-based cards, review this article to convert them to full-stack UI extensions before the sunset date.
Below, learn more about the differences between JSON-based cards and full-stack UI extensions, how to think about conversion, and see an example of converting the previous ZenQuotes cards to function with React.
- JSON-based cards: custom cards built with JSON-based components. These cards use serverless functions to fetch data and build card components on the same layer. This results in the card not being able to respond to different states as the user interacts with it. These cards will be fully deprecated by March 31, 2024.
- Full-stack extensions: extensions in the form of custom cards that are built with React as a frontend framework and serverless functions for fetching and process data. This results in a more dynamic card that can take advantage of states for a more interactive and data-rich experience.
When converting your card, keep in mind the following key differences between JSON-based cards and full-stack UI extensions:
- With full-stack UI extensions, you can think about your front-end and back-end needs separately. In this sense, the UI extension can be treated like a micro-app
- Full-stack UI extensions offer a richer component library with options to make them as interactive as possible using React.
- Full-stack UI extensions support more layout management options through the
Flex
andBox
components, similar to using CSS flexbox. - Full-stack UI extensions enable complete local development support by showing your front end changes in HubSpot without needing to reload the page. You can also take advantage of enhanced debugging options in the browser console and IDE debugger with
console.log()
for a more streamlined building process.
With these differences in mind, it's strongly recommended to use the conversion process as an opportunity to rethink your card's capabilities and overall user experience. Rather than simply rebuilding the card to the new system, you should consider how you'd ideally like the card to function without the constraints that come with JSON-based cards.
Planning
Start the conversion process by:
- Thinking about your desired user experience, keeping in mind that your UI extension can support more flexibility and interactivity.
- Identifying your needs for fetching data using APIs. You'll now be able to split your code for your frontend and backend needs.
- Learning more about how full-stack UI extensions work.
Execution
After planning, get started with full-stack UI extensions:
- Update to the latest version of the CLI by running
npm install -g @hubspot/cli@next
. - Follow the quickstart guide to create your first UI extension.
- After completing the quickstart guide and familiarizing yourself with the new toolset, you can also check out HubSpot's sample projects for inspiration.
- Finally, create a new boilerplate project by running
hs project create
. Based on your learnings, build your re-imagined UI extension card.
As an example, below you'll find an example of recreating the ZenQuotes card as a full-stack UI extension.
Previously, HubSpot provided an example card that fetched and displayed quotes from ZenQuotes.
This card was powered by a single JavaScript file containing a serverless function, as shown in the code below. Over the course of the next few sections, you'll walk through how to recreate this same functionality as a React-based UI extension with a separate back end and front end.
To build this card using the boilerplate project, you'd need to make a few updates to your project, app, and card config files, then split the serverless function code between the serverless function and a new frontend React file.
In the project.json
file, you'll need to add a platformVersion
value, which tells HubSpot which version of the developer platform you're building on. The current version is 2023.2
.
In the app.json
file, you'll need to add a uid
value for the app, which is the app's unique identifier. This can be any string value, and enables you to change the name of the app itself without losing any historical data such as logs. For example, you could set a uid
of getting_started_example_app
.
Previously, the card's JSON config file was contained in the app
folder. Now, however, this file is kept within the app/extensions
folder, which will also contain the eventual frontend React code among other files.
You no longer need to include the fetch
object or targetFunction
. Instead, you'll need to include a uid
to identify the extension, along with a module
object to specify the React file.
The serverless.json
file will be configured as before. However, the serverless function is now dedicated to fetching quotes on the back end, rather than also rendering components.
Next, update the custom-card.js
file name to match the file you specified above (get-quotes.js
). Then, update the serverless function code as follows. Note that you're no longer fetching propertiesToSend
in this file. Instead, you'll be adding that functionality to the React file.
In the src/app/extensions
folder, the Example.jsx
file will handle the frontend code for your extension. This file name needs to match the one specified in the card's JSON config file (in data.module
).
This .jsx
file will call the get-quotes
function, then display that data using components. Additionally, the code below includes a few simple UX improvements, such as an empty state.
Note that this uses a different approach for fetching CRM properties. With full-stack UI extensions, you can use fetchCrmObjectProperties
to fetch CRM properties on the React client side. This is an alternative approach, since you could still include propertiesToSend
inside the serverless function to fetch properties on the backend, which can be better suited when needing the most up-to-date data. Learn more about fetching CRM properties.
Thank you for your feedback, it means a lot to us.