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

tracking-sdk-glazertech

v1.0.7

Published

Event tracking SDK for web

Readme

Tracking SDK GlazerTech

Lightweight web tracking SDK for event tracking, session management, user identification, dynamic link click attribution, offline support, and funnel analytics.

Installation

npm install tracking-sdk-glazertech

Import

Import the SDK at your app entry so click IDs are captured before init() runs (e.g. React useEffect):

import trackingSDK from "tracking-sdk-glazertech";

Initialize

await trackingSDK.init({
  baseURL: "https://your-tracking-api.com",
  apiKey: "your-api-key",
  platform: "web",
  sessionTimeInMinutes: 30,
  clickSessionTimeInMinutes: 10,
  batchSize: 10,
  flushDebounceMs: 2000,
  debug: false,
});

The SDK POSTs to {baseURL}/events and {baseURL}/events/identify-user.

Init options

| Option | Default | Description | |--------|---------|-------------| | baseURL | required | API root URL (trailing slashes trimmed). Events go to {baseURL}/events. | | apiKey | required | Sent as X-API-Key header (secretKey is a legacy alias) | | platform | "web" | Platform label on events | | sessionTimeInMinutes | 30 | Session timeout when no click ID is active | | clickSessionTimeInMinutes | 10 | Session timeout while a link click ID is attributed | | batchSize | 10 | Flush immediately when queue reaches this size | | flushDebounceMs | 2000 | POST ~2s after last track() when batch not full (0 to disable) | | identifyTimeoutMs | 30000 | Max wait when track() is blocked during setUserId | | debug | false | Log every track() to the console |

Call init() once per page (e.g. inside useEffect in React). Calling it twice is safe — browser listeners are not duplicated.

Next.js / React

Import at the top level; call init() in useEffect:

import trackingSDK from "tracking-sdk-glazertech";

export default function RootLayout({ children }) {
  useEffect(() => {
    trackingSDK.init({
      baseURL: process.env.NEXT_PUBLIC_TRACKING_URL,
      apiKey: process.env.NEXT_PUBLIC_TRACKING_KEY,
    });
  }, []);

  return children;
}

The import captures ?cld_<id> from the URL immediately, even if init() runs later after client-side routing.

Dynamic link click attribution

When a user lands on a URL with a click ID query param, the SDK attributes all events to that link click.

URL format: https://your-site.com/page?cld_6a28015189b1fe0640199dcd

The SDK reads cld_<id> and stores only the ID part (6a28015189b1fe0640199dcd).

What happens automatically

| Step | Behavior | |------|----------| | Script import | Click ID captured from URL into sessionStorage (before init()) | | init() | New attributed session starts with 10-minute timeout | | Every track() | clickId sent as a top-level field on each event | | Same link refresh | Keeps existing session and click ID | | Different cld_ link | Old session and click ID removed; new session starts | | 10+ min idle | New session; click ID cleared | | Tab close | sessionStorage clears; fresh session on next visit | | Logout | USER_LOGOUT sent with click ID, then new session without click ID |

SPA navigations (pushState, replaceState, popstate) are also watched so a new cld_ param is captured before init() if the user clicks another link in the same tab.

Late SDK loading (optional fallback)

If the bundle loads only after navigation, add this inline snippet in your HTML <head>:

<script>
(function () {
  try {
    var params = new URLSearchParams(location.search);
    for (var pair of params.entries()) {
      var c = pair[0].startsWith("cld_") ? pair[0] : pair[1].startsWith("cld_") ? pair[1] : "";
      if (c) {
        sessionStorage.setItem("thryl_click_id", c.slice(4));
        sessionStorage.setItem("thryl_click_captured_at", String(Date.now()));
        break;
      }
    }
  } catch (e) {}
})();
</script>

When events are sent

| Trigger | Timing | |---------|--------| | Queue ≥ batchSize | Immediate | | SESSION_START (new session only) | Immediate | | flushDebounceMs after last track() | ~2s (default) | | Tab hidden / pagehide | Immediate | | Back online | Immediate | | Retry worker (failed/offline backlog) | Every 15s |

For instant POST on every event: batchSize: 1, flushDebounceMs: 0.

Track Event

trackingSDK.track("HOME_SCREEN");

trackingSDK.track("TOURNAMENT_DETAILS", {
  category: "tournament",
  tournamentId: 123,
});

Event payload shape

Each event POSTed to {baseURL}/events includes:

| Field | Description | |-------|-------------| | sessionId | Current session ID | | visitorId | Persistent visitor ID (localStorage) | | userId | Set after setUserId() succeeds | | clickId | Present when user arrived via a cld_ link | | category | Lifted to top level when passed in metadata (see below) | | platform | From init() | | eventName | Event name passed to track() | | pageUrl | Current page URL | | timestamp | ISO 8601 string | | metadata | Remaining metadata (without category) |

category in metadata is sent as a separate top-level field for your Node API schema. It is removed from metadata to avoid duplication.

Example payload:

{
  "sessionId": "session_…",
  "visitorId": "visitor_…",
  "userId": "user_123",
  "clickId": "6a28015189b1fe0640199dcd",
  "category": "tournament",
  "platform": "web",
  "eventName": "TOURNAMENT_DETAILS",
  "pageUrl": "https://your-site.com/tournament/123",
  "timestamp": "2026-06-01T12:00:00.000Z",
  "metadata": {
    "tournamentId": 123
  }
}

Identify User

await trackingSDK.setUserId("user_123");

userId is saved locally only after the identify API succeeds. The identify request also includes clickId when a link attribution session is active.

Logout

await trackingSDK.logout();

USER_LOGOUT is flushed immediately.

Debugging

All logs are prefixed with [TrackingSDK] in the browser console.

| Level | When | |-------|------| | failure | Always — init misconfig, API errors, network errors | | warn | Always — offline, track before init, storage errors | | success | Always for init, flush, identifyUser, setUserId, logout, click ID replacement | | success | Per track() only when debug: true |

Filter the console with [TrackingSDK].

Features

  • Automatic Session Management
  • Dynamic Link Click Attribution (cld_ query params)
  • Early Click ID Capture (before init())
  • Visitor Tracking
  • User Identification
  • Category Field Support (top-level on events)
  • Offline Event Queue
  • Automatic Retry
  • Event Batching & Debounced Flush
  • Browser Tab Session Handling
  • Funnel Tracking Support
  • Next.js Compatible
  • React Compatible
  • Vanilla JavaScript Compatible

Example

import trackingSDK from "tracking-sdk-glazertech";

await trackingSDK.init({
  baseURL: "https://your-tracking-api.com",
  apiKey: "your-api-key",
  platform: "web",
  sessionTimeInMinutes: 30,
  clickSessionTimeInMinutes: 10,
});

// User may have landed via ?cld_abc123 — clickId is attached automatically
trackingSDK.track("LOGIN_START", { category: "auth" });

await trackingSDK.setUserId("123");

trackingSDK.track("LOGIN_COMPLETED", { category: "auth" });