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

@klickbee-agency/tracking

v0.6.2

Published

Framework-agnostic analytics client for [klickbee-tracking](https://github.com/), a PostHog/Hotjar-style product analytics tool. Ships ESM + CJS with types, plus an optional React/Next.js integration.

Readme

@klickbee/tracking

Framework-agnostic analytics client for klickbee-tracking, a PostHog/Hotjar-style product analytics tool. Ships ESM + CJS with types, plus an optional React/Next.js integration.

  • Pageviews, custom events, identify, autocapture clicks
  • Optional session replay (rrweb) tied to the analytics session
  • Buffered + batched delivery (timer + size based), sendBeacon on page hide
  • SSR-safe: every method is a no-op on the server
  • Persists an anonymousId (localStorage) and per-tab sessionId (sessionStorage)

Install

This package is published to a self-hosted GitLab Package Registry under the @klickbee scope. Point the scope at the registry in your project (or user) .npmrc, then install as usual. Replace <GITLAB_HOST> and <GITLAB_PROJECT_ID> with your values, and provide an auth token via GITLAB_NPM_TOKEN:

# .npmrc (in the consuming project)
@klickbee:registry=https://<GITLAB_HOST>/api/v4/projects/<GITLAB_PROJECT_ID>/packages/npm/
//<GITLAB_HOST>/api/v4/projects/<GITLAB_PROJECT_ID>/packages/npm/:_authToken=${GITLAB_NPM_TOKEN}
export GITLAB_NPM_TOKEN=<personal-or-deploy-token-with-read_package_registry>
pnpm add @klickbee/tracking
# React integration also needs react / react-dom (peer deps)

Core usage

import { createClient } from "@klickbee/tracking";

const tracking = createClient({
	projectKey: "pk_live_xxx",
	apiHost: "http://localhost:3020", // events POST to `${apiHost}/api/ingest`
	autocapture: true, // optional, capture clicks
	flushAt: 20, // optional, flush after N events (default 20)
	flushInterval: 5000, // optional, flush every N ms (default 5000)
	debug: false,
});

tracking.pageview();
tracking.track("signup_clicked", { plan: "pro" });
tracking.identify("user_123", { email: "[email protected]" });
tracking.reset(); // on logout: clears identity + new anonymousId
tracking.flush(); // force-send buffered events

Config

| Option | Type | Default | Description | | --------------- | --------- | -------- | ---------------------------------------------------- | | projectKey | string | N/A | Public ingest key (pk_...). | | apiHost | string | N/A | klickbee-tracking origin. | | autocapture | boolean | false | Capture document clicks as autocapture events. | | replay | boolean | false | Record a session replay (rrweb) tied to this session.| | flushAt | number | 20 | Flush once the buffer reaches this many events. | | flushInterval | number | 5000 | Flush cadence in milliseconds. | | debug | boolean | false | Log internal activity to the console. | | requireConsent | boolean | false | Capture/send nothing until grantConsent() is called. | | respectDoNotTrack | boolean | true | Honour the browser Do-Not-Track signal (full no-op). |

Privacy / GDPR controls

Consent gating

With requireConsent: true the client captures nothing, starts no timers, runs no replay and makes no network calls until you explicitly grant consent. The decision is persisted in localStorage (kb_consent) and auto-resumed on the next load.

const tracking = createClient({
	projectKey: "pk_...",
	apiHost: "https://analytics.example.com",
	requireConsent: true,
});

// After the visitor accepts your cookie/consent banner:
tracking.grantConsent(); // starts timers, scroll, autocapture, replay (if configured)

// If they later withdraw consent:
tracking.revokeConsent(); // stops replay + tracking, clears the buffer, stops timers

Do-Not-Track

respectDoNotTrack defaults to true. When the browser signals DNT (navigator.doNotTrack === "1", window.doNotTrack, or navigator.msDoNotTrack), the client becomes a full no-op regardless of consent: no timers, no autocapture, no replay, no network. Set respectDoNotTrack: false to ignore the signal.

Replay PII masking

Session replay masks personal data by default:

  • All typed input values are masked (maskAllInputs: true), with password, email and tel inputs always masked.

  • You can opt elements out of the recording with these selectors:

    | Marker | Effect | | ------------------------------- | ------------------------------------------------- | | data-kb-block / .kb-block | Block the element entirely (replaced by a box). | | data-kb-mask / .kb-mask | Mask the element's text content. | | data-kb-ignore / .kb-ignore | Ignore the element (its changes aren't recorded). |

    <input class="kb-block" name="ssn" />
    <div data-kb-mask>Account balance: $12,345</div>
    <div data-kb-ignore>noisy live widget</div>

These defaults are overridable when constructing a ReplayRecorder directly via maskAllInputs, blockSelector and maskTextSelector, but masking always takes precedence over the fidelity options (inlineStylesheet/images/fonts).

Session replay

Set replay: true to record the page with rrweb. The recorder reuses the client's sessionId/anonymousId, buffers the rrweb event stream, and posts bounded chunks to ${apiHost}/api/ingest/replay (flushing on a timer, when the buffer fills, and on page hide via sendBeacon). Recording starts automatically; you can also control it manually:

const tracking = createClient({ projectKey: "pk_...", apiHost: "...", replay: true });
tracking.startReplay(); // idempotent
tracking.stopReplay();

With the React provider, pass replay: true in config; the provider handles it.

Next.js App Router

The SDK never imports next/navigation; the app passes the current pathname so the provider can auto-track pageviews on route changes.

// app/providers.tsx
"use client";

import { TrackingProvider } from "@klickbee/tracking/react";
import { usePathname } from "next/navigation";
import type { ReactNode } from "react";

export function Analytics({ children }: { children: ReactNode }) {
	const pathname = usePathname();
	return (
		<TrackingProvider
			config={{
				projectKey: "pk_...",
				apiHost: "http://localhost:3020",
				autocapture: true,
			}}
			pathname={pathname}
		>
			{children}
		</TrackingProvider>
	);
}
// app/layout.tsx
import { Analytics } from "./providers";

export default function RootLayout({ children }: { children: React.ReactNode }) {
	return (
		<html lang="en">
			<body>
				<Analytics>{children}</Analytics>
			</body>
		</html>
	);
}

Then in any client component:

"use client";
import { useTracking } from "@klickbee/tracking/react";

export function SignupButton() {
	const tracking = useTracking();
	return <button onClick={() => tracking.track("signup_clicked")}>Sign up</button>;
}

Manual pageview wiring

If you prefer to handle pageviews yourself, omit pathname and use the hook:

import { useAutoPageview, useTracking } from "@klickbee/tracking/react";
import { usePathname } from "next/navigation";

const tracking = useTracking();
useAutoPageview(tracking, usePathname());

License

MIT