Last modified: September 3, 2025
Secrets allow you to securely store sensitive information like API keys, tokens, and other credentials that your React modules need for authentication and external service integration. HubSpot provides secure secret management through the CLI and configuration files.

Creating secrets

To start using secrets, create a secret with the hs secrets add command in the HubSpot CLI:
hs secrets add SECRET_NAME
You’ll be prompted to enter the secret value, which will be securely stored in your HubSpot account.

Configuration

Depending on your project structure, you’ll need to configure secrets in different configuration files:

CMS Assets (cms-assets.json)

For CMS React projects, add the names of secrets used by your components to a secretNames array in your cms-assets.json config:
{
  "label": "My CMS project",
  "secretNames": ["API_KEY", "DATABASE_URL", "THIRD_PARTY_TOKEN"]
}

Themes (theme.json)

For theme-based projects, add secrets to your theme.json configuration using the secret_names property:
{
  "label": "My Theme",
  "preview_path": "./templates/home-page.html",
  "screenshot_path": "./images/screenshot.jpg",
  "secret_names": ["API_KEY", "THIRD_PARTY_TOKEN"],
  "version": "1.0",
  "author": {
    "name": "Your Name",
    "email": "your.email@example.com"
  }
}
Note the difference in property names: CMS assets use secretNames (camelCase) while themes use secret_names (snake_case).

Accessing secrets in components

To access secrets in your React components, use the getSecret() function from @hubspot/cms-components:
import { getSecret } from '@hubspot/cms-components';

export async function getServerSideProps(context) {
  const apiKey = getSecret('API_KEY');
  const databaseUrl = getSecret('DATABASE_URL');

  // Perform secure server-side operations
  const response = await fetch(`${databaseUrl}/api/data`, {
    headers: {
      'Authorization': `Bearer ${apiKey}`
    }
  });
  const data = await response.json();

  // Pass only the processed data to your component
  return {
    props: {
      userData: data,
      // Never pass raw secrets as props
    }
  };
}

export function Component({ userData }) {
  return (
    <div>
      {/* Your component JSX */}
    </div>
  );
}
To prevent accidentally leaking secrets, getSecret() can only be called from component code executed on the server and not from the browser (i.e. within an island). The most secure pattern is using secrets in getServerSideProps as shown above, since this ensures secret-handling code never reaches the client bundle.

Security restrictions

To prevent accidentally leaking secrets, getSecret() has important security restrictions:
  • Cannot be called at the top-level of a module - Must be called within a React component function or server-side functions like getServerSideProps
  • Cannot be called from inside an island - Islands run in the browser where secrets would be exposed
  • Server-side only - Secrets are only available during server-side rendering
For the highest level of security, prefer using secrets in getServerSideProps rather than directly in component code, as this ensures secret-handling logic never reaches the client bundle. If you need to pass a secret value to client-side code (which makes it publicly viewable), you must explicitly pass it via an island prop:
import { getSecret } from '@hubspot/cms-components';

export function ServerComponent(props) {
  const apiKey = getSecret('API_KEY');

  // Only pass non-sensitive data or public API keys to islands
  return <ClientIsland publicApiKey={apiKey} />;
}
Security note: Only pass secrets to islands if the value is not sensitive and can be safely exposed to the browser. Never pass private API keys, database credentials, or other sensitive secrets to client-side code.

Local development

To make secrets available during local development with @hubspot/cms-dev-server, create a .env file in your project root to define secret values for local use only. Keys in this file need to be prefixed with HS_ to be recognized by the dev server as secrets:
# .env file
HS_API_KEY=your-local-api-key-value
HS_DATABASE_URL=your-local-database-url
HS_THIRD_PARTY_TOKEN=your-local-token
These secrets will be accessible locally without the HS_ prefix. In the example above, you can access them with:
const apiKey = getSecret('API_KEY');
const databaseUrl = getSecret('DATABASE_URL');
const token = getSecret('THIRD_PARTY_TOKEN');
The .env file is only for local development. Never commit this file to version control as it may contain sensitive information.

Best practices

  1. Use descriptive names - Choose clear, descriptive names for your secrets that indicate their purpose
  2. Minimize secret usage - Only request access to secrets that your components actually need
  3. Keep secrets server-side - Never expose sensitive secrets to client-side code
  4. Use environment-specific secrets - Use different secret values for development, staging, and production environments
  5. Rotate secrets regularly - Update secret values periodically for enhanced security