Skip to main content
Hooks are used to simplify accessing context, performing actions, and fetching CRM data within UI extensions. The hooks provided by the UI extensions SDK are optimized to prevent unnecessary re-renders and automatically clean up resources when components unmount. You can pass inline arrays and objects to the hooks directly, as memoization is not required.

Universal hooks

Universal hooksSupported in all extension points: crm.record.tab, crm.record.sidebar, crm.preview, helpdesk.sidebar, settings, home

useExtensionApi

The useExtensionApi hook provides access to available actions and contextual information from a single hook, for extension components that need access to both actions and context. Otherwise, it’s best practice to use the more specific useExtensionActions or useExtensionContext, depending on your use case. The following example uses the useExtensionApi hook to display an alert (action) containing the user’s first name (context) when a button is clicked.

useExtensionContext

The useExtensionContext hook provides access to contextual information about the current extension environment, including location and other relevant data. For a complete list of available context properties, see the context reference documentation. The following example accesses the current extension location and renders it in a Text component:

useExtensionActions

The useExtensionActions hook provides access to various actions that can be performed within the HubSpot interface. It’s a generic hook that can be typed with specific extension point locations for better TypeScript support. For a complete list of available actions, see the actions reference documentation. The actions available depend on the extension point location. The following example displays an alert when a button is clicked:

useRecordProperties

The useRecordProperties hook fetches properties from the provided CRM record with optional formatting. It accepts an array of properties to fetch, the record ID/type, and an optional object of formatting options. This hook was introduced in the latest version (v1) of the UI Extensions SDK.

useRecordAssociations

The useRecordAssociations hook fetches CRM records of a specific object type associated with the provided record. It accepts an object containing configuration details for the association fetch request. This hook was introduced in the latest version (v1) of the UI Extensions SDK.
string
required
The object type of the record for which associations are being fetched.
integer
The ID of the record for which associations are being fetched.
String
The object type ID to fetch associations from (e.g., ‘0-1’ for contacts).
Array
An optional array of properties to fetch from associated records.
integer
An optional number of records per page (defaults to 10).
object
Contains formatting options for the values returned from date, datetime, and currency properties.
  • The propertiesToFormat properties can be set to "all", or an array of property names to format. Defaults to "all".
  • The date and dateTime objects can include format and relative subfields:
    • format (string): a date or datetime string like MM-DD-YYYY or MM-DD-YYYY:mm:ss. Supports standard date time string formats.
    • relative (boolean): set to true to display the amount of time passed since the returned value (e.g., (1 day ago) or (1 hour ago)).
  • The currency object can include addSymbol (boolean), which sets whether the currency symbol should display with the number. Set to true to display the currency symbol.

useRecordSearch

The useRecordSearch hook searches CRM records of a given object type. The search is built using any combination of text query and structured filters, and returns record IDs, property values, and optional associations. Property values are returned unformatted unless the format option is provided. This hook was introduced in the latest version (v1) of the UI Extensions SDK.
string
required
The object type to search. Accepts type IDs ("0-1"), names ("contact", "deal"), or custom object names with a p_ prefix ("p_pets").
array
An optional array of properties to return for each result.
string
An optional free-text search query matched against the object’s default searchable properties.
array
An optional array of filter groups. Groups in the array are OR’d together; filters within a single group are AND’d. Each filter includes a propertyName, an operator (EQ, NEQ, LT, LTE, GT, GTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN), and a value, values, or highValue field depending on the operator. See search the CRM for more details.
array
An optional array of sort configurations. Each item requires a propertyName and a direction ("ASCENDING" or "DESCENDING").
integer
An optional number of results per page. Default: 10. Max: 200.
object
Contains formatting options for the values returned from date, datetime, and currency properties.
  • The propertiesToFormat properties can be set to "all", or an array of property names to format. Defaults to "all".
  • The date and dateTime objects can include format and relative subfields:
    • format (string): a date or datetime string like MM-DD-YYYY or MM-DD-YYYY:mm:ss. Supports standard date time string formats.
    • relative (boolean): set to true to display the amount of time passed since the returned value (e.g., (1 day ago) or (1 hour ago)).
  • The currency object can include addSymbol (boolean), which sets whether the currency symbol should display with the number. Set to true to display the currency symbol.
Please note: formatting is applied based on property type (date, datetime, currency) rather than content. For example, date formatting will not apply to a string type property containing a date value.

useCrmSearch

The useCrmSearch hook searches CRM records of a given object type. The search is built using any combination of text query and structured filters, and returns record IDs, property values, and optional associations. Property values are returned unformatted unless propertiesToFormat is set.
Please note: this hook is no longer available in the latest version (v1) of the UI extensions SDK. Instead, use the newer useRecordSearch hook instead.
object
required
Configures the search request with the following parameters:
  • objectType required: the object type to search. Accepts type IDs ("0-1"), names ("contact", "deal"), or custom object names with a p_ prefix ("p_pets").
  • properties: an optional array of properties to return for each result.
  • query: an optional free-text search query matched against the object’s default searchable properties.
  • filterGroups: an optional array of filter groups. Groups in the array are OR’d together; filters within a single group are AND’d. Each filter includes a propertyName, an operator (EQ, NEQ, LT, LTE, GT, GTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN), and a value, values, or highValue field depending on the operator. See search the CRM for more details.
  • sorts: an optional array of sort configurations. Each item requires a propertyName and a direction ("ASCENDING" or "DESCENDING").
  • pageLength: an optional number of results per page. Default: 10. Max: 200.
'all' | array
Either 'all' or an array of property names to format. When omitted, property values are returned unformatted.
object
Contains formatting options for the values returned from date, datetime, and currency properties.
  • The date and dateTime objects can include format and relative subfields:
    • format (string): a date or datetime string like MM-DD-YYYY or MM-DD-YYYY:mm:ss. Supports standard date time string formats.
    • relative (boolean): set to true to display the amount of time passed since the returned value (e.g., (1 day ago) or (1 hour ago)).
  • The currency object can include addSymbol (boolean), which sets whether the currency symbol should display with the number. Set to true to display the currency symbol.
Please note: formatting is applied based on property type (date, datetime, currency) rather than content. For example, date formatting will not apply to a string type property containing a date value.

useRecordAggregation (BETA)

The useRecordAggregation hook runs grouped counts and numeric metrics over CRM records, optionally across associated objects, and returns one row per group. HubSpot runs the aggregation server-side, so you don’t need to fetch every record with useCrmSearch and calculate totals in your extension. Use it for summary data like pipeline value by deal stage, revenue by month, or companies that have no deals. A query starts from a root object (from), can join associated objects (joins), groups records by one or more properties (dimensions), and calculates values for each group (measures and calculatedMeasures). You can also filter, sort, and limit the results.
Please note: useRecordAggregation is currently in beta, and is subject to HubSpot’s Developer Terms and Developer Beta Terms. The hook is still under active development, and its API may change based on testing and feedback.Import it from @hubspot/ui-extensions/experimental, available in @hubspot/ui-extensions version 0.18.0 and later 0.x versions.
object
required
The root object to aggregate:
  • objectType required: the object type to aggregate. Accepts type IDs ("0-3"), names ("deal"), or custom object names with a p_ prefix ("p_pets").
  • alias: an optional name for the root object. You can reference it in the source field of dimensions, measures, and filters, and in the joinTo field of joins. Fields that omit source target the root object.
array
An optional array of up to three associated objects to bring into the query. Each join includes:
  • objectType required: the object type to join. It must be associated with the object it joins to.
  • alias required: a name for the joined object, used in source fields.
  • joinTo: the alias of the object to join to. Must be the root object’s alias or the alias of a join that appears earlier in the array. Defaults to the root object.
  • on: the association type to join on, for when more than one association type exists between the two objects. When omitted, HubSpot selects the association automatically. The value is a string in the format "<categoryId>-<typeId>":
    • categoryId is 0 for HubSpot-defined association types, 1 for user-defined association labels, or 2 for integrator-defined association types.
    • typeId is the association type ID for the direction from the joinTo object to the joined object. To find the ID of a custom association label, retrieve the association labels between the two objects.
    For example, "0-342" joins companies to deals using the default company to deal association. If the type ID is for the opposite direction, such as "0-341" (deal to company) on a join from companies to deals, the join finds no associated records instead of returning an error.
Joins keep every record from the object being joined to, even when it has no associated record. The joined object’s values are null for those records.
array
required
The properties to group records by, up to 10. Each unique combination of dimension values produces one row. Pass an empty array to aggregate all matching records into a single row. The row is returned even when no records match, with values like a COUNT of 0. Each dimension includes:
  • property required: the property to group by.
  • source: the alias of the object the property belongs to. Defaults to the root object.
  • as: the key for this dimension in each row. Defaults to the value of property. Set as when two objects in the query share a property name.
  • dateTrunc: groups a date or datetime property into calendar buckets in the account’s time zone. Accepts DAY, WEEK, MONTH, QUARTER, or YEAR. Each bucket’s value is the bucket’s start date as a YYYY-MM-DD string (e.g., "2026-08-01" for August 2026). WEEK buckets start on Monday. Records with no value for the property are grouped into a bucket whose value is null.
array
required
The values to calculate for each group. A query needs at least one entry in measures (calculated measures alone aren’t enough), and can include up to 10 measures and calculated measures combined. Each measure includes:
  • name required: the key for this measure in each row.
  • metric required: the aggregation to perform. Accepts COUNT, SUM, AVERAGE, MIN, MAX, DISTINCT_COUNT, or MEDIAN. Without a field, COUNT counts the root object’s records in each group. With a field, it counts the records where that property has a value. DISTINCT_COUNT returns an exact count of unique values. To count unique records in a query with joins, use DISTINCT_COUNT on the object’s hs_object_id.
  • field: the property to aggregate, as an object with a property and an optional source alias. Required for every metric except COUNT.
  • fixedBy: an array of dimension keys (each dimension’s as or property value). The measure is calculated across only those dimensions, ignoring the query’s other dimensions. For example, in a query grouped by deal stage and owner, a SUM of amount with fixedBy: ["dealstage"] returns each stage’s total on every row for that stage. An empty array behaves the same as omitting fixedBy.
array
An optional array of values derived from two other measures, such as a ratio. Calculated measures count toward the limit of 10 measures. Each calculated measure includes:
  • name required: the key for this value in each row.
  • left required and right required: the name of a measure or another calculated measure. Operands can’t reference dimensions or constant numbers, and calculated measures can’t reference themselves directly or indirectly. An operand that references a measure with fixedBy uses that measure’s regular grouped value, not its fixed value.
  • operator required: the arithmetic to apply to left and right. Accepts ADD, SUBTRACT, MULTIPLY, or DIVIDE.
array
An optional array of filter groups. Groups in the array are OR’d together; filters within a single group are AND’d. Each filter includes:
  • propertyName required: the property to filter on.
  • operator required: the comparison to make. Accepts EQ, NEQ, GT, GTE, LT, LTE, IN, NOT_IN, CONTAINS, NOT_CONTAINS, STARTS_WITH, ENDS_WITH, IS_KNOWN, or IS_UNKNOWN.
  • value: the value to compare against, as a string. Used by every operator except IN, NOT_IN, IS_KNOWN, and IS_UNKNOWN.
  • values: a non-empty array of string values, for the IN and NOT_IN operators.
  • source: the alias of the object the property belongs to. Defaults to the root object.
The GT, GTE, LT, and LTE operators compare numeric values. To filter a date or datetime property, pass a millisecond timestamp as a string (e.g., String(date.getTime())). To find root records with no associated record of a joined type, filter the joined object’s hs_object_id with IS_UNKNOWN.
object
Orders the rows:
  • by required: the key of a dimension, measure, or calculated measure.
  • direction: "ASCENDING" or "DESCENDING". Default: "ASCENDING".
Rows with the same by value are then ordered by their dimension values in ascending order. Without sort, rows are ordered by their dimension values only.
number
The maximum number of rows to return, as a positive integer. Requires sort, so the rows returned are always the top results for that sort. Default: 100. Max: 1000. Larger values are treated as 1000.
Rows are typed from the configuration you pass: each row has a key for every dimension’s as or property value, every measure name, and every calculated measure name. If you define the configuration in a separate variable instead of inline, declare it as const. Without it, TypeScript widens values like metric: "COUNT" to string, and the call doesn’t compile.
When using useRecordAggregation, keep the following in mind:
  • Query limits: a query can include up to three joins, 10 dimensions, and 10 measures (including calculated measures). A query over these limits returns a FAILED error.
  • Truncated results: results are capped rather than paginated. When truncated is true, raise the limit (up to 1,000), narrow your filters, or group by a broader dimension (e.g., MONTH instead of DAY).
  • Timeouts: the hook waits up to 45 seconds for a query to complete, then returns a TIMEOUT error. A query that times out on HubSpot’s side returns a FAILED error.
  • Data freshness: results can come from a cache, so they may not reflect the latest changes to CRM data. Use dataAge to show when the data was last refreshed, and isStale to flag older results. The hook has no refetch function. It runs a new query when its configuration changes or the component remounts, and a new query can still return cached results.
  • Stable configuration: because the hook runs a new query whenever its configuration changes, avoid values that change on every render, such as Date.now(). Round dates to a fixed boundary, like the start of a day or month, instead. Changing the configuration also clears the current rows and sets isLoading to true until the new results arrive.
  • Permissions: your app needs read scopes for the root object and every joined object. If a dimension, measure, or filter uses a sensitive data property and your app doesn’t have the matching sensitive data scope, the whole query fails. Results also respect the viewing user’s record and property permissions.

useDebounce

The useDebounce hook prevents a rapidly-changing value from propagating until it has stopped changing for a given number of milliseconds. Use it to avoid triggering expensive operations (like CRM search API requests) on every change, and instead wait until the user has paused.
The hook accepts any JSON-serializable value: strings, numbers, booleans, null, arrays, and objects. Objects and arrays are compared by deep equality, so a new object reference with the same content won’t reset the debounce timer. Passing a non-serializable value (e.g., a function or a Date object) will result in incorrect deep equality comparisons.
The hook returns the debounced version of value with the same type as the input. On the initial render, value is returned immediately without delay. The pending timer is cancelled when the component unmounts.
Pair useDebounce with useCrmSearch (or any data-fetching hook) to avoid firing a request on every keystroke:

CRM-specific hooks

These hooks are only available in CRM extension points (crm.record.tab, crm.record.sidebar, crm.preview, and helpdesk.sidebar). Ensure you’re on the latest version (v1) of the UI extensions SDK to use these hooks in your app:
Note that the useCrmProperties and useAssociations hooks are no longer available in the latest version (v1) of the UI extensions SDK, and have been replaced with the newer useRecordPropertiesCurrent and useRecordAssociationsCurrent hooks respectively.
Example import usage:

useRecordPropertiesCurrent

As of version v1 of the UI extensions SDK, the useRecordPropertiesCurrent hook has replaced the older useCrmProperties hook. Learn more in the UI extensions SDK versioning guide.
The useRecordPropertiesCurrent hook fetches properties from the current CRM record with optional formatting. It accepts an object that includes an array of properties to fetch, along with an optional object to format the returned data.
array
required
An array of property names to fetch.
object
Contains formatting options for the values returned from date, datetime, and currency properties.
  • The propertiesToFormat properties can be set to "all", or an array of property names to format. Defaults to "all".
  • The date and dateTime objects can include format and relative subfields:
    • format (string): a date or datetime string like MM-DD-YYYY or MM-DD-YYYY:mm:ss. Supports standard date time string formats.
    • relative (boolean): set to true to display the amount of time passed since the returned value (e.g., (1 day ago) or (1 hour ago)).
  • The currency object can include addSymbol (boolean), which sets whether the currency symbol should display with the number. Set to true to display the currency symbol.
Formatting is applied based on property type (date, datetime, currency) rather than content. For example, date formatting will not apply to a string type property containing a date value.

useCrmProperties

Please note: this hook is no longer available in the latest version (v1) of the UI extensions SDK. Instead, use the newer useRecordPropertiesCurrent hook instead.
The useCrmProperties hook fetches properties from the current CRM record with optional formatting. It accepts an array of properties to fetch, along with an optional object to format the returned data.
'all' | array
required
Either 'all' or an array of property names to format.
object
Contains formatting options for the values returned from date, datetime, and currency properties.
  • The date and dateTime objects can include format and relative subfields:
    • format (string): a date or datetime string like MM-DD-YYYY or MM-DD-YYYY:mm:ss. Supports standard date time string formats.
    • relative (boolean): set to true to display the amount of time passed since the returned value (e.g., (1 day ago) or (1 hour ago)).
  • The currency object can include addSymbol (boolean), which sets whether the currency symbol should display with the number. Set to true to display the currency symbol.
Formatting is applied based on property type (date, datetime, currency) rather than content. For example, date formatting will not apply to a string type property containing a date value.

useRecordAssociationsCurrent

The useRecordAssociationsCurrent hook fetches CRM records of a specific object type associated with the currently displaying record. It accepts an object containing the object type ID of the associated record, the properties to fetch from the associated object, an optional number of associated records to retrieve, and an optional object that formats returned property data. This hook was introduced in the latest version (v1) of the UI Extensions SDK.
string
required
The object type ID to fetch associations from (e.g., ‘0-1’ for contacts).
  • properties:
  • pageLength: an optional number of items per page (defaults to 10).
'all' | array
An optional array of properties to fetch from associated records.
integer
An optional number of records per page (defaults to 10).
object
Contains formatting options for the values returned from date, datetime, and currency properties.
  • The propertiesToFormat properties can be set to "all", or an array of property names to format. Defaults to "all".
  • The date and dateTime objects can include format and relative subfields:
    • format (string): a date or datetime string like MM-DD-YYYY or MM-DD-YYYY:mm:ss. Supports standard date time string formats.
    • relative (boolean): set to true to display the amount of time passed since the returned value (e.g., (1 day ago) or (1 hour ago)).
  • The currency object can include addSymbol (boolean), which sets whether the currency symbol should display with the number. Set to true to display the currency symbol.

useAssociations

Please note: this hook is no longer available in the latest version (v1) of the UI extensions SDK. Instead, use the newer useRecordAssociationsCurrent hook instead.
The useAssociations hook fetches CRM records of a specific object type associated with the currently displaying record. It accepts an object containing configuration details for the association fetch request, and an optional object that formats returned property data.
object
required
Configures the association data fetch request with:
  • toObjectType: the object type ID to fetch associations from (e.g., ‘0-1’ for contacts).
  • properties: an optional array of properties to fetch from associated records.
  • pageLength: an optional number of items per page (defaults to 10).
'all' | array
required
Either 'all' or an array of property names to format.
object
Contains formatting options for the values returned from date, datetime, and currency properties.
  • The date and dateTime objects can include format and relative subfields:
    • format (string): a date or datetime string like MM-DD-YYYY or MM-DD-YYYY:mm:ss. Supports standard date time string formats.
    • relative (boolean): set to true to display the amount of time passed since the returned value (e.g., (1 day ago) or (1 hour ago)).
  • The currency object can include addSymbol (boolean), which sets whether the currency symbol should display with the number. Set to true to display the currency symbol.

Best practices

Always use TypeScript generics

Extract hook calls to component level

Last modified on November 2, 2026