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

@velocityio/web-attribution-sdk

v0.1.0

Published

Velocity attribution & conversion tracking SDK

Readme

Velocity Web Attribution SDK

Velocity's attribution & conversion tracking SDK for advertisers. Report conversion events (Purchase, Lead, AddToCart, or custom events) back to Velocity, tied to the ad click that drove the visit.

  • Full documentation: https://docs.velocity.io/web/attribution
  • API reference: https://docs.velocity.io/web/attribution/api-reference

Backend status: not yet live. The conversion ingestion endpoints (browser and S2S) are specifications the backend has not implemented yet — events sent today will not be recorded.

Installation

npm install @velocityio/web-attribution-sdk

Quick Start

import { VelocityAttribution, StandardEvents } from '@velocityio/web-attribution-sdk';

const attribution = new VelocityAttribution({ advertiserKey: 'YOUR_ADVERTISER_KEY' });
attribution.setConsent(true); // required — nothing is sent until consent is granted

attribution.track(StandardEvents.Purchase, {
  eventId: 'ORD-123', // dedup key, shared with any server-side postback
  value: 49.99,
  currency: 'USD'
});

API Reference

| Method | Description | |--------|-------------| | new VelocityAttribution({ advertiserKey, cookieDomain?, disableCookies?, timeout?, logger? }) | advertiserKey is required — usually the only field you need. cookieDomain overrides the auto-detected eTLD+1; disableCookies forces localStorage-only. Both are escape hatches for unusual deployments. | | setConsent(granted) | GDPR consent. true unblocks sending and attribution storage; false stops sending and clears the stored click ID and browser ID. | | setDoNotSell(optOut) | CCPA "Do Not Sell" flag, transmitted on every event as privacy.do_not_sell. | | track(eventName, params?, useBeacon?) | params accepts { eventId, value, currency, orderId, contents, custom }. Pass useBeacon = true from a page-unload handler so delivery uses navigator.sendBeacon instead of fetch. Events tracked while consent is still pending are buffered (up to 20) and sent once consent is granted. | | destroy() | Releases listeners and buffered events. Call on SPA component unmount or before creating a replacement instance; not needed on standard multi-page sites. |

Standard Events

PageView, ViewContent, Search, AddToCart, InitiateCheckout, AddPaymentInfo, Purchase, Lead, CompleteRegistration, StartTrial, Subscribe, Contact — exported as StandardEvents. Custom names are also accepted.

Purchase events should include value and currency (a debug warning is logged when missing).

Event Deduplication (eventId)

Every event carries an event_id. Supply your own via params.eventId when the same event may also arrive from your server — Velocity deduplicates on (advertiser key, event name, event id). For Purchase, your order ID is a good choice. Auto-generated UUID when omitted.

Server-to-Server (S2S) Events

Your backend can also report conversions directly over HTTPS — no SDK needed. Send batched events to the documented endpoint with Authorization: Bearer <apiSecret> (a server-side secret issued per account), using the same event schema and the same event_id for browser/server deduplication. See the S2S Conversions API spec for the full contract, including how to forward the first-party _vlc/_vlp cookies for attribution.

How Click Attribution Works (click_id)

  1. A user clicks a Velocity ad. Velocity's click redirect appends a click_id query parameter to your landing page URL (e.g. https://shop.example.com/?click_id=abc123). This requires the campaign to be served through Velocity's redirect — without it there is no click_id and conversions arrive unattributed.
  2. On page load the module captures click_id from the URL and — once tracking consent is established — persists it as a first-party cookie (_vlc, 90 days) on your registrable domain (eTLD+1), with localStorage as a same-origin fallback. A fresh click_id always overwrites a stored one (last click wins).
  3. Later funnel pages with no click_id in the URL fall back to the stored value — the cookie scope means attribution survives cross-subdomain funnels (shop.example.comcheckout.example.com) as well as multi-page checkouts. It does not carry across a different registrable domain.
  4. Every track() call attaches whichever click ID is current; conversions without one are still sent, just unattributed.

The module also maintains a first-party browser ID (_vlp cookie, ~13 months, plus a localStorage mirror) — a random UUID attached to every event as a secondary match signal, created only once consent permits and cleared on denial.

Both IDs are self-healing: they are held in memory for the page lifetime and re-persisted on every track() call and on tab-hide, so third-party scripts wiping cookies/localStorage mid-session cannot permanently remove them (consent denial always wins over healing).

Consent & Privacy

The SDK supports GDPR and CCPA compliance with automatic CMP detection and explicit consent APIs.

Automatic CMP Detection

The SDK automatically reads consent signals from any IAB TCF v2 compatible CMP (OneTrust, Didomi, etc.) via the standard __tcfapi interface. No configuration needed — if a CMP is present on the page, the SDK reads its consent data.

Explicit Consent API

// Set consent at construction time
const attribution = new VelocityAttribution({ 
  advertiserKey: 'YOUR_KEY'
});

// Or set consent dynamically
attribution.setConsent(true); // GDPR consent granted
attribution.setConsent(false); // GDPR consent revoked
attribution.setDoNotSell(true); // CCPA opt-out

How It Works

track() is gated client-side: while consent is unknown or denied, calls are no-ops and no request leaves the browser. A detected IAB TCF v2 CMP is read automatically (TCF Purpose 1), the same as the main SDK. Explicitly denying consent also clears all stored attribution IDs. The consent state is transmitted on every event as consent.ad_storage (granted / denied / unknown) plus the raw TCF string when a CMP is present.

Page Unload Tracking

window.addEventListener('pagehide', () => {
  attribution.track('Lead', { eventId: 'ORD-123' }, true); // sendBeacon
});

The third parameter (useBeacon = true) ensures delivery uses navigator.sendBeacon instead of fetch, which guarantees events send even as the page unloads.

Cleanup & Lifecycle

Call destroy() when the SDK instance is no longer needed to release all internal resources:

attribution.destroy();

This releases listeners and buffered events. After calling destroy(), the instance cannot be reused — create a new VelocityAttribution instance if needed.

When to call destroy():

  • SPA route transitions where the SDK is no longer needed
  • Component unmount in frameworks like React/Vue/Angular
  • Before creating a new SDK instance with different configuration

When you don't need destroy():

  • Standard multi-page sites (page unload cleans up automatically)
  • Single SDK instance that lives for the entire page session

CDN & Google Tag Manager

Direct-install (CDN script snippet) and Google Tag Manager integrations are also available. See the attribution documentation for:

  • CDN installation instructions
  • GTM template configuration
  • Advanced consent management
  • Event schema reference
  • Troubleshooting guide

Documentation

For the complete integration guide, visit the Velocity attribution documentation.

License

MIT