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

@linkzly/web-sdk

v1.0.3

Published

Full-featured browser SDK for Linkzly — event tracking, attribution, sessions, and deep linking

Downloads

235

Readme

@linkzly/web-sdk

Platform TypeScript License

Full-featured browser SDK for Linkzly — event tracking, attribution, session management, and deep linking for web applications. Zero dependencies, < 6KB gzipped.

Features

  • Event Tracking — Custom events, page views, purchases with automatic batching
  • Session Management — Automatic visibility-based sessions (30s timeout, matching mobile SDKs)
  • Attribution Tracking — UTM parameters, referrer capture, smart link handling
  • Deep Link / Smart Link — Parse and handle Linkzly smart links with SPA support
  • User Identification — Persistent visitor ID + custom user ID
  • Privacy Controls — DNT/GPC respect, opt-out controls, GDPR-friendly
  • Offline Queue — localStorage-backed event queue with retry and sendBeacon on unload
  • Scroll Depth — Automatic max scroll depth tracking per page
  • Outbound Click Tracking — Automatic external link click tracking
  • Time on Page — Automatic session duration tracking
  • SPA Support — History API hooks for pushState/popstate navigation

Requirements

  • Any modern browser (Chrome 66+, Firefox 60+, Safari 12+, Edge 79+)
  • No dependencies

Installation

npm / yarn

npm install @linkzly/web-sdk
# or
yarn add @linkzly/web-sdk

CDN (UMD)

<script src="https://cdn.linkzly.com/web-sdk/latest/index.js"></script>
<script>
  LinkzlySDK.configure('YOUR_SDK_KEY');
</script>

Quick Start

import LinkzlySDK from '@linkzly/web-sdk';

// Initialize
LinkzlySDK.configure('YOUR_SDK_KEY');

// Track events
LinkzlySDK.trackEvent('button_click', { button_id: 'signup' });

// Track purchases
LinkzlySDK.trackPurchase({
  order_id: 'ORD-123',
  amount: 99.99,
  currency: 'USD',
});

// Set user ID after login
LinkzlySDK.setUserID('user_12345');

Named Imports (Tree-Shakeable)

import { configure, trackEvent, trackPageView, setUserID } from '@linkzly/web-sdk';

configure('YOUR_SDK_KEY');
trackEvent('signup_completed', { method: 'google' });

API Reference

Configuration

configure(sdkKey, environment?, options?)

Initialize the SDK. Must be called before any other method.

import LinkzlySDK, { Environment } from '@linkzly/web-sdk';

LinkzlySDK.configure('YOUR_SDK_KEY', Environment.PRODUCTION, {
  autoTrackPageViews: false,  // opt-in SPA page view tracking (default: false)
  autoTrackSessions: true,    // visibility-based sessions (default: true)
  autoExtractUTM: true,       // auto-capture UTM params (default: true)
  autoCaptureReferrer: true,  // auto-capture document.referrer (default: true)
  respectDNT: true,           // honor Do Not Track / GPC (default: true)
  batchSize: 20,              // events per batch (default: 20)
  flushIntervalMs: 30000,     // flush timer (default: 30s)
  sessionTimeoutMs: 30000,    // session timeout (default: 30s)
  debug: false,               // console logging (default: false, auto-true in DEVELOPMENT)
});

Environments:

  • Environment.PRODUCTION — Production endpoint (default)
  • Environment.STAGING — Staging endpoint
  • Environment.DEVELOPMENT — Development endpoint with verbose logging

Event Tracking

trackEvent(eventName, parameters?)

Track a custom event.

LinkzlySDK.trackEvent('add_to_cart', {
  product_id: 'SKU-123',
  quantity: 2,
  price: 49.99,
});

trackPageView(pageUrl?, parameters?)

Track a page view. Called automatically if autoTrackPageViews: true.

LinkzlySDK.trackPageView(); // current page
LinkzlySDK.trackPageView('/products/123', { category: 'electronics' });

trackPurchase(parameters?)

Track a purchase event.

LinkzlySDK.trackPurchase({
  order_id: 'ORD-98765',
  total: 599.99,
  currency: 'USD',
  items: 3,
});

trackEventBatch(events)

Track multiple events in one call.

LinkzlySDK.trackEventBatch([
  { eventName: 'screen_view', parameters: { screen: 'home' } },
  { eventName: 'button_click', parameters: { button: 'signup' } },
]);

flushEvents()

Manually flush all queued events to the server.

await LinkzlySDK.flushEvents();

getPendingEventCount()

Get the number of events waiting in the queue.

const count = LinkzlySDK.getPendingEventCount();

Deep Link / Smart Link

handleSmartLink(url?)

Parse a URL into deep link data (matching mobile SDK pattern).

const data = LinkzlySDK.handleSmartLink();
// { url, path, parameters, smartLinkId, clickId }

const data = LinkzlySDK.handleSmartLink('https://example.com/product?id=123&slid=abc');

addDeepLinkListener(listener)

Listen for SPA navigation events (requires autoTrackPageViews: true).

const unsubscribe = LinkzlySDK.addDeepLinkListener((data) => {
  console.log('Navigation:', data.path, data.parameters);
});

// Cleanup
unsubscribe();

User Management

setUserID(userID) / getUserID() / clearUserID()

LinkzlySDK.setUserID('user_12345');
const id = LinkzlySDK.getUserID(); // 'user_12345'
LinkzlySDK.clearUserID();

getVisitorID() / resetVisitorID()

Persistent device/browser identifier (survives across sessions).

const visitorId = LinkzlySDK.getVisitorID(); // UUID persisted in localStorage
const newId = LinkzlySDK.resetVisitorID();   // generates new UUID

Session Management

const sessionId = LinkzlySDK.getSessionId();
LinkzlySDK.startSession();  // force new session
LinkzlySDK.endSession();    // end current session

Sessions auto-manage via the Page Visibility API — a new session starts when the page becomes visible after 30+ seconds of being hidden.

Privacy Controls

LinkzlySDK.setTrackingEnabled(false); // disable all tracking
const enabled = LinkzlySDK.isTrackingEnabled();

The SDK respects navigator.doNotTrack and navigator.globalPrivacyControl by default. Set respectDNT: false in config to override.

Cleanup

LinkzlySDK.destroy(); // remove all listeners, flush events, stop timers

Framework Examples

React / Next.js

import { useEffect } from 'react';
import LinkzlySDK, { Environment } from '@linkzly/web-sdk';

export default function App({ children }) {
  useEffect(() => {
    LinkzlySDK.configure('YOUR_SDK_KEY', Environment.PRODUCTION, {
      autoTrackPageViews: true, // enable for Next.js SPA navigation
    });

    return () => LinkzlySDK.destroy();
  }, []);

  return <>{children}</>;
}

Vue 3

// main.ts
import { createApp } from 'vue';
import LinkzlySDK from '@linkzly/web-sdk';
import App from './App.vue';

LinkzlySDK.configure('YOUR_SDK_KEY');
createApp(App).mount('#app');

Vanilla JS

<script type="module">
  import LinkzlySDK from '@linkzly/web-sdk';

  LinkzlySDK.configure('YOUR_SDK_KEY');

  document.getElementById('buy-btn').addEventListener('click', () => {
    LinkzlySDK.trackEvent('button_click', { button: 'buy' });
  });
</script>

Auto-Tracked Web Features

These features use the existing event payload structure (customData field) — no database changes required.

| Feature | Event Name | Data Collected | |---------|-----------|----------------| | Scroll Depth | scroll_depth | max_depth_percent, page_url | | Time on Page | time_on_page | duration_seconds, page_url | | Outbound Clicks | outbound_click | destination_url, link_text, page_url |

Scroll depth and time on page are sent automatically on page unload via sendBeacon. Outbound clicks are tracked in real-time.

Event Delivery

  • Batching: Up to 20 events per batch (configurable), max 100 per network request
  • Queue: Events persisted in localStorage (up to 500, 24h expiry)
  • Flush triggers: Batch size reached, 30s timer, flushEvents(), page unload
  • Unload: navigator.sendBeacon() for reliable delivery on page close
  • Retry: Exponential backoff (1s, 2s, 4s) with max 3 retries on 5xx/429

Data Collected

When tracking is enabled, the SDK collects:

  • Browser information (user agent, language, screen size, viewport, timezone)
  • Page URL and referrer (external only)
  • UTM parameters from URL
  • Smart link / click attribution IDs
  • Custom event data (provided by your application)

Not collected:

  • Personal user information (unless explicitly provided via setUserID)
  • Location data (beyond IP-based geo-location server-side)

Note: For affiliate attribution tracking (cookie-based click IDs, checkout form helpers, S2S conversion payloads), use the separate @linkzly/affiliate-web package.

License

MIT

Support

  • Documentation: https://docs.linkzly.com
  • Issues: https://github.com/linkzly/linkzly-web-sdk/issues
  • Email: [email protected]