react-clickmap
Docs/Overview

Getting Started

Wrap your app with `ClickmapProvider` and drop a `Heatmap` overlay wherever you want to visualize behavior:

Install

Shell
npm install react-clickmap

Quick setup

Wrap your app with ClickmapProvider and drop a Heatmap overlay wherever you want to visualize behavior:

TSX
import { ClickmapProvider, Heatmap, fetchAdapter } from "react-clickmap";

// The adapter tells react-clickmap where to send and load events.
// fetchAdapter sends events to your own API endpoint via HTTP.
const adapter = fetchAdapter({ endpoint: "/api/clickmap" });

export function App() {
  return (
    <ClickmapProvider
      adapter={adapter}
      projectId="my-app"
      capture={["click", "scroll", "rage-click", "dead-click"]}
      sampleRate={0.25}
      respectDoNotTrack
      respectGlobalPrivacyControl
    >
      <YourApp />

      {/* Show a heatmap overlay for the /pricing page */}
      <Heatmap adapter={adapter} page="/pricing" type="heatmap" />
    </ClickmapProvider>
  );
}

That's all the client-side code you need. Events are automatically captured, batched, and sent to your endpoint.

What happens under the hood

  1. Capture — Browser listeners detect clicks, scrolls, pointer movement, rage clicks, and dead clicks. Each event is normalized with viewport-relative coordinates, device type, and a unique event ID.
  2. Batch — Events are queued in an internal batcher. The batcher flushes to your adapter every 5 seconds, when 100 events accumulate, or when the user navigates away (via pagehide/visibilitychange).
  3. Persist — Your adapter's save() method receives the batch. With fetchAdapter, this is an HTTP POST to your endpoint. You handle storage however you like.
  4. Render — The <Heatmap> component calls your adapter's load() method to fetch events, then renders a GPU-accelerated overlay using WebGL (with Canvas fallback).

Capture modes

ModeWhat it captures
clickEvery click with viewport-relative x/y coordinates and pointer type
dead-clickClicks on non-interactive elements (e.g., plain text, images) — signals layout confusion
rage-click3+ rapid clicks within a small radius — signals user frustration
scrollCurrent scroll depth and maximum scroll depth reached
pointer-moveMouse/touch movement coordinates — used for attention heatmaps

Enable only the modes you need:

TSX
<ClickmapProvider
  adapter={adapter}
  capture={["click", "scroll"]}  // Only track clicks and scroll depth
>

Provider props

PropTypeDefaultDescription
adapterClickmapAdapterrequiredWhere to save and load events
projectIdstring"default"Scopes events by project
userIdstringOptional user identifier for per-user queries
captureCaptureType[]["click"]Which event types to capture
sampleRatenumber1Fraction of sessions to capture (0–1)
flushIntervalMsnumber5000How often to flush the event queue
maxBatchSizenumber100Max events per batch before flushing early
respectDoNotTrackbooleanfalseHonor the browser's Do Not Track signal
respectGlobalPrivacyControlbooleanfalseHonor the Global Privacy Control signal
consentRequiredbooleanfalseRequire explicit consent before capturing
hasConsentbooleanCurrent consent state (used with consentRequired)
maskSelectorsstring[][]CSS selectors for elements to mask in events
ignoreSelectorsstring[][]CSS selectors for elements to exclude entirely

Choosing an adapter

react-clickmap is storage-agnostic. Pick the adapter that matches your stack:

AdapterInstallUse case
memoryAdapter()built-inDevelopment and testing — events live in memory
localStorageAdapter()built-inBrowser-only prototyping — events persist in localStorage
fetchAdapter()built-inProduction — sends events to your HTTP endpoint
createPostgresAdapter()npm install @react-clickmap/postgresDirect Postgres persistence with parameterized queries
createSupabaseAdapter()npm install @react-clickmap/supabaseSupabase REST API — no backend code needed

See the Persistence Guide for detailed setup instructions with each adapter.

Next steps