---
title: Heap
description: Load Heap with c15t and gate autocapture product analytics behind
  measurement consent.
group: integrations
icon: heap
lastModified: "2026-08-04T19:55:26+01:00"
---
[Heap](https://www.heap.io/) provides product analytics with automatic interaction capture, identity APIs, event properties, and pageview tracking. The `heap()` helper creates Heap's current heap.js v5 callback queue, records your environment ID and optional client configuration, and loads Heap only when `measurement` consent is available.

## Integrate with c15t

**React**

```tsx
import { type ReactNode } from 'react';
import { ConsentManagerProvider } from '@c15t/react';
import { heap } from '@c15t/scripts/heap';

const scripts = [
  heap({
    envId: 'YOUR_APP_ID',
    clientConfig: {
      disableTextCapture: true,
    },
  }),
];

export function ConsentProvider({ children }: { children: ReactNode }) {
  return (
    <ConsentManagerProvider
      options={{
        mode: 'hosted',
        backendURL: 'https://your-instance.c15t.dev',
        scripts,
      }}
    >
      {children}
    </ConsentManagerProvider>
  );
}
```

**Next.js**

```tsx
'use client';

import { type ReactNode } from 'react';
import { ConsentManagerProvider } from '@c15t/nextjs';
import { heap } from '@c15t/scripts/heap';

const scripts = [
  heap({
    envId: 'YOUR_APP_ID',
    clientConfig: {
      disableTextCapture: true,
    },
  }),
];

export function ConsentProvider({ children }: { children: ReactNode }) {
  return (
    <ConsentManagerProvider
      options={{
        mode: 'hosted',
        backendURL: '/api/c15t',
        scripts,
      }}
    >
      {children}
    </ConsentManagerProvider>
  );
}
```

**JavaScript**

```ts
import { getOrCreateConsentRuntime } from 'c15t';
import { heap } from '@c15t/scripts/heap';

getOrCreateConsentRuntime({
  mode: 'hosted',
  backendURL: 'https://your-instance.c15t.dev',
  scripts: [
    heap({
      envId: 'YOUR_APP_ID',
      clientConfig: {
        disableTextCapture: true,
      },
    }),
  ],
});
```

## How c15t loads it

* **Category:** `measurement` (Analytics)
* **Loads when:** measurement consent is granted
* **On revocation:** unloaded - c15t removes the script element it created. `window.heap` and `window.heapReadyCb` remain until the next page load (c15t reloads the page on revocation by default), and Heap has no documented browser opt-out API — treat the load gate as the consent boundary.

The helper maps Heap's current web installation snippet into the manifest engine:

```ts
heap({
  envId: 'YOUR_APP_ID',
  clientConfig: {
    disableTextCapture: true,
  },
});
```

It creates `window.heapReadyCb` and `window.heap`, records:

```ts
window.heap.envId = 'YOUR_APP_ID';
window.heap.appid = 'YOUR_APP_ID';
window.heap.clientConfig = {
  disableTextCapture: true,
  shouldFetchServerConfig: false,
};
```

and loads:

```txt
https://cdn.us.heap-api.com/config/YOUR_APP_ID/heap_config.js
```

Heap's config script then chain-loads the versioned heap.js runtime for that environment. The official snippet stores queued calls as `{ name, fn }` records in `window.heapReadyCb`; c15t reproduces that callback queue instead of using tuple queues such as `['track', ...args]`.

`envId` is required and must be a non-empty string after trimming. Heap app IDs are commonly numeric strings, but Heap's public install docs describe the value as your app ID, so c15t does not enforce a numeric-only format.

## Configure heap.js

Pass `clientConfig` as the second Heap load argument. Values must be JSON-serializable: plain objects, arrays, strings, finite numbers, booleans, and `null`.

```ts
import { heap } from '@c15t/scripts/heap';

heap({
  envId: 'YOUR_APP_ID',
  clientConfig: {
    disableTextCapture: true,
    disableSessionReplay: true,
    metadataStorage: 'localstorage',
  },
});
```

c15t always adds `shouldFetchServerConfig: false`, matching Heap's current installation snippet. Do not pass functions, Dates, Maps, Sets, class instances, symbols, `undefined`, `NaN`, or infinite numbers in `clientConfig`.

To proxy or self-host the config loader, pass a custom URL:

```ts
heap({
  envId: 'YOUR_APP_ID',
  scriptUrl: 'https://analytics.example.com/heap_config.js',
});
```

## Consent behavior

c15t blocks Heap from loading until `measurement` consent is granted and unloads it on revocation. Heap autocaptures interactions when heap.js runs, and its web installation docs do not document a consent-mode-style runtime opt-out API that c15t can call to make an already-loaded SDK inert after consent is withdrawn.

That makes the consent gate on load the consent boundary: no Heap config loader, heap.js runtime, cookies, localStorage, automatic page tracking, or interaction capture should start before the user grants `measurement` consent. See the [RudderStack consent notes](/docs/integrations/rudderstack#consent-behavior) for the broader reasoning behind blocking SDK load when a vendor API cannot guarantee denied-by-default collection semantics.

## Tracking events in your app

c15t gates Heap from loading until `measurement` consent is granted. Your application code that calls Heap's runtime API (`window.heap.track`, `identify`, etc.) is **not** automatically gated - `window.heap` does not exist until the script is loaded, so unguarded calls before consent throw.

Guard event calls by checking consent state. From React:

```tsx
import { useCallback } from 'react';
import { useConsentManager } from '@c15t/react';

function SignupExample() {
  const { has } = useConsentManager();

  const trackSignup = useCallback(() => {
    if (has('measurement')) {
      window.heap?.track('Signup Completed', { plan: 'pro' });
    }
  }, [has]);
}
```

From plain JavaScript:

```ts
import { getOrCreateConsentRuntime } from 'c15t';

const { consentStore } = getOrCreateConsentRuntime();

if (consentStore.getState().has('measurement')) {
  window.heap?.track('Signup Completed', { plan: 'pro' });
}
```

## Types

### HeapOptions

|Property|Value|
|:--|:--|
|Type Name|\`HeapOptions\`|
|Source Path|\`./packages/scripts/src/vendors/analytics/heap.ts\`|

\*ExtractedTypeTable: Could not extract "HeapOptions" from "./packages/scripts/src/vendors/analytics/heap.ts" using base path "/vercel/path0/apps/c15t-docs/.leadtype/c15t". Verify the path/name and that the file is included by your tsconfig.\*

### Script

|Property|Value|
|:--|:--|
|Type Name|\`Script\`|
|Source Path|\`./packages/core/src/libs/script-loader/types.ts\`|

\*ExtractedTypeTable: Could not extract "Script" from "./packages/core/src/libs/script-loader/types.ts" using base path "/vercel/path0/apps/c15t-docs/.leadtype/c15t". Verify the path/name and that the file is included by your tsconfig.\*
