Skip to content

Repository files navigation

@vllnt/analytics

Lightweight, privacy-first analytics library with consent management and React integration.

Features

  • Event tracking with pre-init queuing (no lost events during hydration)
  • Consent management — two categories (analytics + functional), localStorage + SSR cookie
  • Versioned consent — bump version to re-prompt users
  • Do Not Track — respects browser DNT setting
  • SSR-safe — all browser APIs guarded
  • Zero external analytics dependencies — bring your own backend (Vercel Analytics, GA, custom)

Install

pnpm add @vllnt/analytics

Peer dependency: react ^18.0.0 || ^19.0.0

Usage

React Provider

import{AnalyticsProvider}from'@vllnt/analytics/react'functionApp(){return(<AnalyticsProviderconfig={{app: 'my-app',version: 1,debug: true}}>{children}</AnalyticsProvider>)}

Consent Banner

import{useConsent}from'@vllnt/analytics/react'functionCookieBanner(){const{ hasResponded, isLoading, acceptAll, declineAnalytics }=useConsent()if(isLoading||hasResponded)returnnullreturn(<div><p>We use cookies for analytics.</p><buttononClick={acceptAll}>Accept</button><buttononClick={declineAnalytics}>Decline</button></div>)}

Track Events

import{track,trackPage}from'@vllnt/analytics'// Generic eventtrack('button_click',{id: 'cta-hero'})// Page viewtrackPage({path: '/about'})

Tutorial Tracking

Typed helpers for tutorial/content flows:

import{trackTutorialStart,trackSectionView,trackSectionComplete,trackTutorialComplete,trackTutorialNavigation,trackTimeSpent,}from'@vllnt/analytics'trackTutorialStart({tutorial_id: 'getting-started',tutorial_title: 'Getting Started',locale: 'en',total_sections: 5,})trackSectionView({tutorial_id: 'getting-started',tutorial_title: 'Getting Started',locale: 'en',section_id: 'intro',section_index: 0,total_sections: 5,})

Identify Users

import{identify,resetAnalytics}from'@vllnt/analytics'// After loginidentify('user-123',{plan: 'pro'})// After logoutresetAnalytics()

Consent Utilities (non-React)

import{loadConsent,saveConsent,clearConsent,createAcceptAllConsent,createDeclineAnalyticsConsent,getConsentFromCookie,isDoNotTrackEnabled,needsRePrompt,}from'@vllnt/analytics'// SSR: read consent from cookie headerconstanalyticsAllowed=getConsentFromCookie(request.headers.cookie)// Check if re-prompt needed after version bumpconstconsent=loadConsent()if(consent&&needsRePrompt(consent,2)){clearConsent()}

API

Core

FunctionDescription
initAnalytics(config)Initialize analytics singleton
track(name, properties?)Track a custom event
trackPage(properties?)Track a page view
identify(userId, traits?)Identify a user
resetAnalytics()Clear user identity (logout)
enableAnalytics(config)Re-enable after consent granted
disableAnalytics()Disable after consent revoked
isAnalyticsEnabled()Check if tracking is active

Consent

FunctionDescription
loadConsent()Load consent from localStorage
saveConsent(state)Persist consent to localStorage + cookie
clearConsent()Remove consent (triggers re-prompt)
createAcceptAllConsent()Create accept-all consent state
createDeclineAnalyticsConsent()Create analytics-declined state
updateConsentCategory(state, category, value)Update a single category
needsRePrompt(consent, version)Check if version requires re-prompt
getConsentFromCookie(cookieString)Parse consent from cookie (SSR)
isDoNotTrackEnabled()Check browser DNT setting

React (@vllnt/analytics/react)

ExportDescription
AnalyticsProviderContext provider — wires consent + analytics init
useAnalytics()Access full analytics context
useConsent(options?)Standalone consent hook for banner UIs

How It Works

User visits site
│
├─ DNT enabled? ──▶ Block all tracking
│
├─ Consent exists?
│ ├─ Version outdated? ──▶ Clear & re-prompt
│ ├─ Analytics declined? ──▶ Block tracking
│ └─ Analytics accepted ──▶ Initialize & flush queue
│
└─ No consent ──▶ Queue events until user responds

Events fired before initialization are queued and flushed once consent is granted and analytics initializes.

Scripts

pnpm test# Run tests (watch mode)
pnpm test:once # Run tests once
pnpm test:coverage # Run with coverage
pnpm lint # Lint
pnpm lint:fix # Lint + autofix

License

MIT

About

Lightweight privacy-first analytics library with consent management, DNT detection, and React hooks

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages