HubSpot UI Extensions Examples

repository·main·Indexed 41 days ago

https://github.com/hubspot/ui-extensions-examples

A collection of practical examples for building React-based UI extensions for HubSpot CRM. Includes a Legacy CRM Card to UI Extension Converter for migrating legacy cards to the modern framework, and a demonstration of bi-directional CRM property refresh using onCrmPropertiesUpdate and refreshObjectProperties.

Tokens
28.2K
Snippets
81
Records
117
Agent score
51%

What's inside HubSpot UI Extensions Examples

  1. Overview of Flex and Box layout samples

    main

    The flex-and-box sample demonstrates layout management in custom cards using <Flex> and <Box> components. Both cards are designed to appear on the Deal object.

    Available Cards

    1. Flex playground card

    File: src/app/cards/FlexPlayground.tsx This card allows you to experiment with various Flex props in real-time. You can add or remove tiles and modify properties to understand how spacing and alignment work together in your own extensions.

    2. Flex and Box example card

    File: src/app/cards/FlexAndBoxExample.tsx This is a functional example of a real estate listing card for deal records. It demonstrates how to use Flex and Box to arrange complex information and multiple components. It includes a form to add property listings, though input is not persisted across refreshes.

  2. Overview of CRM data components sample

    main

    This React project demonstrates how to use HubSpot CRM Components through UI Extensions (UIE). It showcases two primary extensions:

    1. Association Table: Displays important deals associated with the current user. It demonstrates the use of pre-filters, quick filters, and property projections.
    2. Stage Tracker: Displays high-level properties and a property list filtered by pipeline.

    Key capabilities demonstrated:

    • Using HubSpot's CRM Data Components.
    • Utilizing new styling and layout components available through UIE.
    • Making API calls to the HubSpot API using serverless functions.
    • Fetching properties for the current object.
  3. Key features demonstrated in the Duplicate a contact sample

    main

    The 'Duplicate a contact' sample is a React-based extension that demonstrates how to duplicate a contact along with its deal and company associations and specific contact properties.

    It serves as a reference for implementing:

    • Async fetching: Using HubSpot serverless functions to retrieve data.
    • State management: Handling loading and error states within the UI.
    • GraphQL: Making GraphQL calls inside serverless functions.
  4. Use the Custom Logger for debugging

    main

    The Custom Logger allows you to debug UI extensions by sending messages with different severity levels. This is useful for investigating extension failures using Trace IDs.

    Supported Logging Levels

    • info
    • debug
    • warn
    • error

    Features

    • Serverless Request Logging: Built-in logging for serverless requests.
    • Local Development: When running locally, logs are sent directly to your browser/terminal console.
    • Deployed Logging: When the project is uploaded to HubSpot, logs are persisted in the HubSpot logging system and can be retrieved from your app dashboard at: https://app.hubspot.com/private-apps/<portal-id>/<app-id>

    For detailed API documentation, refer to the HubSpot UI Extensions SDK documentation.

  5. Migrate legacy CRM cards to UI extensions using the Converter

    main
    The Legacy CRM Card to UI Extension Converter is an example project designed to help you migrate legacy CRM cards to modern UI extension cards on HubSpot's developer platform. It provides a UI extension card that mimics the behavior of legacy cards, fetching data from a configurable API and displaying it using tiles, expandable content, and action buttons. This allows you to test and develop your new card before fully migrating it to your production app.
  6. Key Components of the Multi-Step Flow Sample

    main

    The multi-step flow sample is composed of several React components that manage different stages of the ordering process:

    • OrderMealCard.tsx: Manages the overall extension state and handles the final order submission.
    • RestaurantsSearch.tsx: Implements paginated search functionality for finding restaurants.
    • MenuPanelContent.tsx: Renders the selected restaurant's menu within a UI Panel.
    • Cart.tsx: Displays the current items in the order or an empty state message.
    • Checkout.tsx: Handles order total calculations and collects contact messages.
  7. Update backend API for JSON body support

    main

    Legacy CRM cards sent requests as application/x-www-form-urlencoded. However, HubSpot's hubspot.fetch API for UI Extensions only supports JSON bodies for POST, PUT, and PATCH methods.

    To ensure compatibility, your backend API must be updated to accept action request parameters in either of these formats:

    1. Query parameters: e.g., ?userId=123&associatedObjectId=456...
    2. JSON body: e.g., {"userId": "123", "associatedObjectId": "456"...}

    Your backend should handle both query parameters and JSON bodies alongside the legacy application/x-www-form-urlencoded format to maintain backwards compatibility during the transition.

  8. Use the useCrmSearch hook for CRM record searching

    main

    The useCrmSearch hook, available from @hubspot/ui-extensions/experimental, allows you to search CRM records directly from a UI extension app page.

    Key capabilities include:

    • Object Selection: Search any standard or custom object type.
    • Property Selection: Choose specific properties to fetch and display.
    • Full-text Search: Implement search with debounced input.
    • Complex Filtering: Build filter groups with multiple conditions.
    • Sorting: Sort results by any fetched property.
    • Pagination: Navigate through large result sets.
    • Formatting: Handle property value formatting (e.g., dates, currencies).

    In the crm-search-hook-demo project, a 'Hook Usage' panel dynamically generates the exact useCrmSearch code snippet matching your current UI configuration, which you can copy into your own application.

  9. Use Panel and Modal components for overlays

    main
    The Overlay example is designed to demonstrate how to implement overlays in HubSpot UI extensions using the <Panel> and <Modal> components. These components are used to present information or user interactions in a layered manner over the existing UI, following HubSpot's design guidelines for use cases like contextual information or focused tasks.
  10. How bi-directional CRM property refresh works

    main

    This example demonstrates how to synchronize CRM property values between a custom UI extension card and the parent HubSpot record page without requiring manual page reloads. It uses three key functions to achieve bi-directional updates:

    1. Listening to external changes: When a user updates a property anywhere else on the parent record page (or via a CRM data component), the custom card can listen for these changes using onCrmPropertiesUpdate. Once a change is detected, the card uses fetchCrmObjectProperties to retrieve the latest values.
    2. Updating from the card: When a user updates a property directly within the custom card, the developer uses HubSpot's public APIs to perform the update. To ensure the card's own UI stays in sync with the newly updated data, the developer calls refreshObjectProperties to enforce a refresh of the local property state.
  11. Differences between Legacy CRM Cards and UI Extension Converters

    main

    When migrating from legacy CRM cards to the UI Extension Converter, be aware of several key behavioral and technical changes:

    Action Request Body Format

    • Legacy cards: POST, PUT, and PATCH requests use application/x-www-form-urlencoded.
    • UI Extension Converter: POST, PUT, and PATCH requests send data as JSON in the request body. GET and DELETE requests continue to use query parameters.
    • Requirement: Update your backend API to accept parameters in either query parameters or a JSON body, as the hubspot.fetch API only supports JSON bodies for POST, PUT, and PATCH and does not support custom Content-Type headers.

    Card Title

    • Legacy cards: Titles can be updated dynamically (e.g., "Issues (5)").
    • UI Extension Converter: Titles are static. They are configured in the hsmeta file and cannot be changed by React code at runtime. To show dynamic counts, display them within the card content (e.g., in a header).

    Settings Actions

    • Legacy cards: Settings actions appear in the card footer.
    • UI Extension Converter: Settings actions are rendered as a button with a settings gear icon. HubSpot recommends creating a dedicated UI extension settings page instead of using the settings action iframe.

    App ID Query Parameter

    • Legacy cards: appId is not included in data fetch requests or action hooks.
    • UI Extension Converter: appId is automatically included in all data fetch requests and action hooks. Your backend must be prepared to handle this parameter to identify which HubSpot app is making the request.
  12. Best Practice: Generate Lockfiles for Projects

    main

    To prevent running out of file descriptors during builds and to streamline subsequent builds, you should always generate package lockfiles before uploading projects.

    To generate a lockfile, run the following command within your project directory: hs project install-deps.

    hs project install-deps