Imported from HubSpot/hubspot-project-components (
2026.03-beta/defaultFiles/AGENTS.md). Install upstream withnpx skills add HubSpot/hubspot-project-components --skill defaultFiles. Copyright stays with the author.
AGENTS.md
This file provides guidance to AI coding agents when working on HubSpot components
IMPORTANT: IF THE 'HubSpotDev' MCP SERVER IS INSTALLED USE THE TOOLS BEFORE TRYING TO MANUALLY USE CLI COMMANDS OR BEFORE TRYING TO DO ANYTHING WITH HUBSPOT ASSETS
HubSpot Project Information
- The project configuration is in the
hsproject.jsonfile - A directory is considered a part of the project if it or a directory above it contains a
hsproject.jsonfile - The project src directory is defined in the
srcDirfield in thehsproject.json - The project's platform version is defined in
platformVersionin thehs project.json - The
platformVersiondetermines what features the project has access to as well as the shape of the configuration files
Local Development
Local Development Server (hs project dev)
- Start a local development server with
hs project devto view extension changes without refreshing - The server runs on your local machine and syncs changes to HubSpot in real-time
- When the server is running, UI extensions (cards, settings pages) display a "Developing locally" tag
- Saving changes to JSX files automatically refreshes the page
Local Proxy Configuration (local.json)
- During local development, you can proxy
hubspot.fetch()requests to a locally running backend - Create a
local.jsonfile in the same directory as your app's*-hsmeta.jsonfile - The proxy configuration maps HTTPS URLs to local URLs:
{ "proxy": { "https://example.com": "http://localhost:8080" } } - Important: Proxy URLs must be valid HTTPS URLs (the key, not the value)
- Path-based routing is NOT supported (e.g.,
"https://example.com/a": "http://localhost:8080"will not work) - When a
local.jsonfile is detected, the CLI confirms the proxy is active - To disable the proxy, rename the file to
local.json.bakand restart the dev server
Request Signing with CLIENT_SECRET
- You can inject the
CLIENT_SECRETenvironment variable when starting the local dev server:CLIENT_SECRET="abc123" hs project dev - This enables request signing during local development for testing secure backend communications
npm packages
@hubspot/ui-extensions
- In the
@hubspot/ui-extensionsnpm package, only the component properties defined by the component are valid.styleproperties are not valid
hubspot.fetch API
hubspot.fetchis a function provided by@hubspot/ui-extensionsfor making HTTP requests from UI components- Critical:
hubspot.fetchrequires fully qualified domain names (FQDN) with HTTPS - relative paths are NOT supported - All URLs must be added to the
permittedUrls.fetcharray in the app's*-hsmeta.jsonconfiguration file - Example:
"permittedUrls": { "fetch": ["https://api.example.com", "https://api.hubapi.com"], "iframe": [], "img": [] } - Fetch URLs must be valid HTTPS URLs and cannot be
localhost - To call a local backend during development, use the
local.jsonproxy configuration (see Local Development section)
Component Information
General
- Component configuration files must end with
-hsmeta.json - The
uidfield in the-hsmeta.jsonfiles must be unique with the project - The
typefield in the-hsmeta.jsonfiles defines the type of the component - Components can not be in nested subdirectories, only the specified directories in their corresponding component rules.
- Example components can be found in https://github.com/HubSpot/hubspot-project-components. The directories are split up by platform version and follow this format
${platformVersion}/components. Note the project create tool only supports platform versions >= 2025.2. - All component subdirectories must be in the project source directory
app component
- There can only be one
appcomponent appcomponent must be in theappdirectory- If the
config.distributionfield is set tomarketplace, the only validconfig.auth.typevalue isoauth
card
cardcomponents must be in theapp/cardsdirectory- The global
windowobject is not available in thecardcomponent - Cannot use
window.fetch, and instead must use thehubspot.fetchfunction provided by the@hubspot/ui-extensionsnpm package. Any urls called with thehubspot.fetchfunction must be added to theconfig.permittedUrls.fetcharray in theappcomponent's hsmeta.json file hubspot.fetchrequires fully qualified HTTPS URLs (e.g.,https://api.example.com/endpoint) - relative paths like/api/endpointare NOT supported- Only components exported from the
@hubspot/ui-extensionsnpm package can be used incardcomponents
Available Hooks for Card Components
Prefer hooks over hubspot.fetch — use hooks to access CRM data and extension context before falling back to hubspot.fetch for external HTTP requests. Hooks must be called at the component level, not inside conditionals or loops. The list below may not be exhaustive — refer to the hooks documentation as the source of truth for all available hooks and their parameters.
Universal hooks (available across all extension points):
useExtensionApi- Access both context and actions from a single hookuseExtensionContext- Access contextual information about the extension environment (portal, user, extension metadata)useExtensionActions- Access all available actions for the current extension pointuseCrmSearch- Search CRM recordsuseDebounce- Debounce a rapidly-changing value
CRM-specific hooks (available in crm.record.tab, crm.record.sidebar, crm.preview, helpdesk.sidebar extension points):
useCrmProperties- Fetch properties from the current CRM recorduseAssociations- Fetch associated CRM records
Available Actions for Card Components
Access actions via the useExtensionActions hook or the actions parameter from hubspot.extend(). The list below may not be exhaustive — refer to the actions documentation as the source of truth for all available actions and their parameters.
Universal actions (available across all extension points):
addAlert- Display an alert bannerreloadPage- Reload the current pagecopyTextToClipboard- Copy text to clipboard; requires explicit user interactioncloseOverlay- Close an open overlay or modal by its idopenIframeModal- Open a URL in an iframe modal
CRM-specific actions (available in crm.record.tab, crm.record.sidebar, crm.preview, helpdesk.sidebar extension points):
fetchCrmObjectProperties- Fetch property values from the current CRM recordrefreshObjectProperties- Refresh CRM record properties in the UI without a full page reloadonCrmPropertiesUpdate- Subscribe to UI-level changes to CRM properties
Context Object
Access context via the useExtensionContext hook or the context parameter from hubspot.extend(). The list below may not be exhaustive — refer to the context documentation as the source of truth for all available context fields.
Universal fields (available on all extension points):
location- Extension point identifierportal.id/portal.timezone/portal.dataHostingLocation- Account infouser.id/user.email/user.firstName/user.lastName/user.locale/user.language/user.teams/user.permissions- User infovariables- Project configuration variables
CRM-specific fields (available in crm.record.tab, crm.record.sidebar, crm.preview, helpdesk.sidebar extension points):
crm.objectId- Current CRM record's IDcrm.objectTypeId- Record type IDextension.appId/extension.appName/extension.cardTitle- Extension metadata
Logging
Use the logger API to send custom log messages. In local development mode, logs go to the browser console only; in production they are sent to HubSpot and viewable via hs project logs. The list below may not be exhaustive — refer to the logging documentation as the source of truth for all available logging methods.
logger.info- Informational messageslogger.debug- Debug messageslogger.warn- Warning messageslogger.error- Error messages
app-event
app-eventcomponents must be in theapp/app-eventsdirectory
app-object
app-objectcomponents must be in theapp/app-objectdirectory
app-function
app-functioncomponents must be in theapp/functionsdirectoryapp-functioncomponents are not available whenconfig.distributionis set tomarketplacein theappcomponent-hsmeta.sonfile
settings
- There can only be one
settingscomponent settingscomponents must be in theapp/settingsdirectory- The global
windowobject is not available in thesettingscomponent - Cannot use
window.fetch, and instead must use thehubspot.fetchfunction provided by the@hubspot/ui-extensionsnpm package. Any urls called with thehubspot.fetchfunction must be added to theconfig.permittedUrls.fetcharray in theappcomponent'shsmeta.jsonfile hubspot.fetchrequires fully qualified HTTPS URLs - relative paths are NOT supported- Only components exported from the
@hubspot/ui-extensionsnpm package can be used insettingscomponents - React Components from
@hubspot/ui-extensions/crmcannot be used insettingscomponents
scim
- There can only be one
scimcomponent scimcomponents must be in theapp/scimdirectory
webhooks
- There can only be one
webhookscomponent. webhookscomponents must be in theapp/webhooksdirectory
workflow-actions
workflow-actioncomponents must be in theapp/workflow-actionsdirectory
HubSpot CLI commands
- All the commands and subcommands have a
--helpargument that provides details on the command and it's arguments - The help output is standard yargs output
- The commands for working with projects in HubSpot are subcommands of
hs project - Debugging flag that can be added to
hscommands and subcommands:--debug - Debugging problems with CLI installation:
hs doctor
Project Commands
hs project create- Create a new HubSpot project interactivelyhs project upload- Upload the project to HubSpot (build is created automatically)hs project deploy- Deploy a specific build of the project to make it livehs project dev- Start a local development server for real-time development of UI extensionshs project watch- Watch for file changes and automatically upload themhs project list- List all projects in the accounths project download- Download a project from HubSpot to localhs project open- Open the current project page in the browserhs project logs- View logs for deployed projectshs project list-builds- List all builds for a projecths project validate- Validate project configuration fileshs project migrate- Migrate a project to a newer platform versionhs project migrate-app- Migrate a legacy app to the projects frameworkhs project clone-app- Clone an existing app configurationhs project lint- Run linting on cards, settings, and page components
Account Management
hs init- Initial setup of the hubspot configuration filehs account auth- Authenticate a new account (requires browser interaction)hs account list- List all configured accountshs account use- Switch the default accounths account info- Display information about an accounths account rename- Rename an account in the confighs account remove- Remove an account from the confighs account clean- Clean up invalid/expired authenticationhs account create-override- Create a project-specific account overridehs account remove-override- Remove a project-specific account override
CMS Commands
hs cms upload <src> <dest>- Upload files to HubSpoths cms fetch <src> <dest>- Download files from HubSpoths cms watch <src> <dest>- Watch for changes and automatically uploadhs cms list <path>- List remote files in HubSpoths cms delete <path>- Delete files from HubSpoths cms mv <srcPath> <destPath>- Move/rename files in HubSpoths cms function list- List all serverless functionshs cms function logs <path>- View logs for a serverless functionhs create template <name>- Create a new templatehs create module <name>- Create a new modulehs create function <name>- Create a new serverless functionhs theme preview- Preview a theme locally at https://hslocal.net:3000/
Sandbox Management
hs sandbox create- Create a development sandbox accounths sandbox delete- Delete a sandbox account
Secrets Management
hs secret list- List secrets for serverless functionshs secret add <name> <value>- Add a secreths secret update <name> <value>- Update a secreths secret delete <name>- Delete a secret
Test Account Management
hs test-account create- Create a configurable test accounths test-account delete- Delete a test accounths test-account import-data- Import test data
General
- Follow existing patterns in the codebase
- Use proper component structure based on component
typein the-hsmeta.jsonfile - Ensure configuration files follow HubSpot naming conventions
- Always validate that components are placed in correct directories
- When working with UI extensions, remember that
hubspot.fetchrequires HTTPS URLs inpermittedUrls.fetch - Use
hs project devfor iterative development of cards and settings pages - Use
local.jsonto proxy API requests to a local backend during development
