Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.hubspot.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

In addition to the logs that are automatically surfaced by the extension logs panel, you can send your own log messages using the logger API provided by the UI extensions SDK. When an extension fails to load on a CRM record, an error message will display. This error message will contain a trace ID, which you can use to locate the custom log messages within the extension’s logs.
logger-debug-on-crm-record
Learn more about monitoring and debugging UI extensions during local development and after deployment using HubSpot’s built-in logging and monitoring tools.

Methods

The following methods are available. Each method accepts a single string argument.
  • logger.info
  • logger.debug
  • logger.warn
  • logger.error
Log panel displaying custom log messages.
For example, the following extension code includes a few different log messages to help better identify where an error has occurred:
import React from "react";
import { Button, Divider, Flex, hubspot, logger, Text } from "@hubspot/ui-extensions";

logger.warn("Warning in the middle tab, before my extension");

hubspot.extend(({ context }) => <MiddleTabLogging context={context} />);

const MiddleTabLogging = ({ context }) => {
  logger.debug(JSON.stringify(context, null, 2));

  const callFetchSuccess = () => {
    return hubspot
      .fetch("https://jsonplaceholder.typicode.com/posts/1", { method: "GET" })
      .then(response => response.json())
      .then(result => logger.info(JSON.stringify(result, null, 2)))
      .catch(error => logger.error(error.message));
  };

  const callFetchFail = () => {
    return hubspot
      .fetch("https://jsonplaceholder.typicode.com/posts/404", { method: "GET" })
      .then(response => {
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        return response.json();
      })
      .then(result => logger.info(JSON.stringify(result, null, 2)))
      .catch(error => logger.error(error.message));
  };

  return (
    <Flex direction="column" align="start" gap="small">
      <Text>Test out the logger with the following buttons.</Text>
      <Text variant="microcopy">The browser's developer console will show your events in local dev.</Text>
      <Divider />
      <Text>Test fetch functions</Text>
      <Flex gap="small" wrap="wrap">
        <Button onClick={callFetchSuccess}>Fetch success ✅</Button>
        <Button onClick={callFetchFail}>Fetch error ❌</Button>
      </Flex>
      <Divider />
      <Flex direction="column" gap="small">
        <Text>Test different log levels.</Text>
        <Flex gap="small" wrap="wrap">
          <Button onClick={() => logger.info("Logging an info!")}>logger.info()</Button>
          <Button onClick={() => logger.debug("Logging a debug!")}>logger.debug()</Button>
          <Button onClick={() => logger.warn("Logging a warning!")}>logger.warn()</Button>
          <Button onClick={() => logger.error("Logging an error!")}>logger.error()</Button>
        </Flex>
      </Flex>
      <Divider />
      <Text>
        Deploy the app and crash the card. Use the Trace ID to see what happened in the Log Traces tab in your private
        app's dashboard.
      </Text>
      <Button
        variant="destructive"
        onClick={() => {
          throw new Error("Card crashed");
        }}
      >
        Crash the card
      </Button>
    </Flex>
  );
};

Notes and limitations

  • Custom log messages are not sent while in local development mode. They are logged to the browser console instead.
  • All logs are sent as batches with a maximum of 100 logs per batch.
  • Each HubSpot account is rate limited to 1,000 logs per minute. After exceeding that limit, all logging is stopped until the page is reloaded.
  • The logger will queue a maximum of 10,000 pending messages. Any subsequent logs will be dropped until the queue is below the maximum.
  • Queued logs are processed at a rate of five seconds per log batch.
  • Queued logs are dropped when the page or is refreshed or closed.
Last modified on May 20, 2026