npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-clickmap

v0.3.0

Published

Privacy-first heatmaps for React. Your data, your database, zero cloud.

Readme

react-clickmap

Privacy-first heatmaps for React. Your data, your database, zero cloud.

Install

npm install react-clickmap

Features

  • Click, scroll, pointer-move capture
  • Dead-click and rage-click detection, capturable independently (e.g. capture={['dead-click']} alone works and won't also store plain clicks)
  • Privacy controls (Do Not Track, Global Privacy Control, selector masking, sampling)
  • Pluggable storage adapter interface, plus a built-in fetchAdapter for HTTP persistence
  • Heatmap, clickmap, and scroll-depth visualizations
  • Full-page, document-relative heatmaps (coordinateSpace="document") for long scrollable pages
  • Comparison heatmap overlays (before/after)
  • Attention heatmap (scroll depth + interaction weighting)
  • Element click-count overlay badges
  • Export helpers (toDataUrl, toBlob, download) via Heatmap ref — WebGL contexts preserve the drawing buffer, so exports work on the WebGL renderer too, not just the Canvas fallback
  • WebGL-preferred renderer (WebGL2 → WebGL1 → Canvas2D) with your custom gradient palette honored on every tier
  • Ships with a "use client" directive in the built output, so it works out of the box in Next.js App Router / RSC trees

Basic Usage

import {
  ClickmapProvider,
  type HeatmapHandle,
  Heatmap,
  memoryAdapter
} from 'react-clickmap';
import { useRef } from 'react';

const adapter = memoryAdapter();

export function Demo() {
  const heatmapRef = useRef<HeatmapHandle>(null);

  return (
    <ClickmapProvider adapter={adapter} capture={['click', 'scroll']}>
      <main>...</main>
      <Heatmap
        ref={heatmapRef}
        adapter={adapter}
        page="/"
        type="heatmap"
        showElementClicks
      />
    </ClickmapProvider>
  );
}

Capture types

capture accepts any combination of 'click' | 'scroll' | 'pointer-move' | 'rage-click' | 'dead-click'. Each type is gated independently — enabling 'dead-click' or 'rage-click' on its own does not also emit 'click' events, so capture={['dead-click']} gives you dead-click signal without storing every plain click. Include 'click' explicitly if you also want raw clicks recorded.

Full-page (document-relative) heatmaps

By default overlays are viewport-relative: a position: fixed layer sized to the window, correct for above-the-fold analysis. For long, scrollable pages, render a full-page heatmap that spans the whole document:

<Heatmap adapter={adapter} page="/" coordinateSpace="document" />

In document mode the overlay is a position: absolute layer sized to document.documentElement.scrollHeight, and points are placed from document-relative coordinates that the capture engine records alongside the viewport ones. It re-renders on resize as the document reflows. Mount <Heatmap> in a non-position: relative container (e.g. directly under body) so the overlay aligns with the document origin.

coordinateSpace also works on AttentionHeatmap and ElementClickOverlay. ScrollDepth is unchanged.

Every coordinate event stores both frames additively:

  • Viewport: x / y (percentages of the viewport).
  • Document: docX / docY (percentages of scrollWidth / scrollHeight) plus docWidth / docHeight (absolute px at capture time, useful for breakpoint analysis).

Old data: events captured before v0.3 have no document coordinates and are skipped in document mode (they still render normally in the default viewport mode). No migration of existing rows is required — the new fields are additive and default to unset.

Breakpoint filtering: filter any heatmap to a device class with device="mobile" | "tablet" | "desktop". The stored viewport.width (and docWidth) let you bucket by breakpoint in your own queries when you need finer granularity.

Persisting events over HTTP

import { fetchAdapter } from 'react-clickmap';

const adapter = fetchAdapter({
  endpoint: '/api/clickmap',
  headers: { Authorization: 'Bearer <token>' }, // optional
});

fetchAdapter prefers navigator.sendBeacon on page exit for reliability. sendBeacon can't carry custom headers, though, so as soon as headers is set, save() always uses fetch(..., { keepalive: true }) instead — even for the page-exit flush — rather than silently dropping the configured headers. Batches larger than maxPayloadBytes (default 64 KB) are split automatically either way.

API Surface

  • Provider: ClickmapProvider
  • Hooks: useClickmap, useHeatmapData
  • Visualization: Heatmap, ScrollDepth, HeatmapThumbnail
  • Advanced: ComparisonHeatmap, AttentionHeatmap
  • Overlay: ElementClickOverlay
  • Adapters: fetchAdapter, memoryAdapter, localStorageAdapter, createAdapter
  • Rendering utilities: detectRenderCapability, DEFAULT_GRADIENT, aggregateElementClicks

License

MIT