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

user-analytics-tracker

v4.7.0

Published

Comprehensive analytics tracking library with device detection, network analysis, location tracking, and IP geolocation

Readme

user-analytics-tracker

npm version License: MIT CI Security

A comprehensive, lightweight analytics tracking library for React applications. Track device information, network type, user location, attribution data, and more—all with zero runtime dependencies (React as peer dependency).

🔒 Privacy-First & Self-Hosted: All analytics data is sent to your own backend server. No data is sent to third-party servers. You have full control over your analytics data.

✨ Features

  • 🔍 Device Detection: Automatically detects device type, OS, browser, model, brand, and hardware specs using User-Agent Client Hints
  • 🌐 Network & Connection Info: Accurate ISP and connection details from ipwho.is API (ASN, organization, domain)
  • 📍 Location Tracking:
    • IP-based location - Requires user consent (privacy-compliant)
    • GPS location - Requires explicit user consent and browser permission
    • Includes public IP address, country, city, region, timezone, continent, flag, connection details
    • Dynamic key storage: All IP location API fields are automatically captured
    • Automatic fallback from GPS to IP when GPS unavailable
    • Consent management utilities included
  • 🎯 Attribution Tracking: UTM parameters, referrer tracking, first/last touch attribution
  • 📊 IP Geolocation: Client-side and server-side IP-based location detection utilities
  • 🔒 Privacy-First: User consent required for location tracking (GPS & IP), consent management utilities
  • 🎯 Custom Event Tracking: Firebase/Google Analytics-style event tracking with automatic context collection
  • Event Batching & Queue System: Automatic event batching reduces API calls by 50-90%. Events are queued and sent in configurable batches with offline persistence
  • 🔄 Retry Logic: Automatic retry with exponential backoff for failed requests. Configurable retry attempts and delays
  • 📝 Enhanced Logging: Configurable log levels (silent, error, warn, info, debug) with automatic dev/prod level selection
  • 🔌 Plugin System: Extensible plugin architecture for event transformation, filtering, and enrichment
  • 📈 Session Management: Enhanced session tracking with timeout detection and automatic renewal
  • 🐛 Debug Tools: Built-in debugging utilities for development (queue inspection, manual flush, stats)
  • 📊 Performance Metrics: Optional metrics collection for monitoring events, retries, and performance
  • Lightweight: Zero runtime dependencies (except React)
  • 📦 TypeScript: Fully typed with comprehensive type definitions
  • 🎨 Framework Agnostic Core: Core detectors work without React
  • 🧪 Well Tested: Comprehensive test suite with Vitest

📦 Installation

npm install user-analytics-tracker react react-dom
# or
yarn add user-analytics-tracker react react-dom
# or
pnpm add user-analytics-tracker react react-dom

Note: React and React-DOM are peer dependencies and must be installed separately.

🔒 Self-Hosted Analytics - Configure Your Backend URL

All analytics data is sent to YOUR backend server - no third-party servers involved. You have complete control over your data.

Quick Configuration

Simply provide your backend URL in the apiEndpoint configuration:

import { useAnalytics } from 'user-analytics-tracker';

function App() {
  const analytics = useAnalytics({
    config: {
      apiEndpoint: 'https://api.yourcompany.com/analytics', // Your backend URL
    },
  });
}

Advanced Configuration Options

The package now supports extensive configuration options for batching, retry logic, logging, and more:

const analytics = useAnalytics({
  config: {
    apiEndpoint: 'https://api.yourcompany.com/analytics',
    
    // Event batching configuration
    batchSize: 10,              // Events per batch (default: 10)
    batchInterval: 5000,        // Flush interval in ms (default: 5000)
    maxQueueSize: 100,          // Max queued events (default: 100)
    
    // Retry configuration
    maxRetries: 3,              // Max retry attempts (default: 3)
    retryDelay: 1000,           // Initial retry delay in ms (default: 1000)
    
    // Session configuration
    sessionTimeout: 1800000,    // Session timeout in ms (default: 30 min)
    
    // Logging configuration
    logLevel: 'warn',           // 'silent' | 'error' | 'warn' | 'info' | 'debug' (default: 'warn')
    
    // Metrics configuration
    enableMetrics: false,       // Enable metrics collection (default: false)
    
    // IP Geolocation - optional. For paid users in browser use proxyUrl so API key is not exposed (see docs)
    ipGeolocation: {
      proxyUrl: '/api/ip-geolocation', // recommended for paid: browser → your backend → ipwho.is (key on server only)
      // Or direct: apiKey, baseUrl, ip (server-side). Do not put apiKey in client when using proxyUrl.
      timeout: 5000,
    },
    
    // Field storage configuration (optional) - control which fields are stored
    fieldStorage: {
      ipLocation: { mode: 'essential' },    // IP location fields (includes connection data)
      deviceInfo: { mode: 'essential' },   // Device info fields
      // networkInfo: Not stored in essential mode - use connection from ipwho.is instead
      location: { mode: 'essential' },     // Location fields
      attribution: { mode: 'essential' },   // Attribution fields
      // Each can be: 'essential' (default) | 'all' | 'custom'
      // For 'custom': specify fields array
      // For 'all': specify exclude array
    },
    
    // Legacy: IP Location storage (backward compatible)
    ipLocationFields: { mode: 'essential' },
  },
});

Configuration Options

You can configure your backend URL in three ways:

1. Full URL (Recommended for Production)

Use a complete URL pointing to your backend server:

const analytics = useAnalytics({
  config: {
    // Point to your own server
    apiEndpoint: 'https://api.yourcompany.com/analytics',
    
    // Or with a custom port
    // apiEndpoint: 'https://api.yourcompany.com:8080/analytics',
    
    // Or using a subdomain
    // apiEndpoint: 'https://analytics.yourcompany.com/track',
  },
});

2. Relative Path (Same Domain)

Use a relative path if your API is on the same domain as your frontend:

const analytics = useAnalytics({
  config: {
    // Sends to: https://yourdomain.com/api/analytics
    apiEndpoint: '/api/analytics',
  },
});

3. Environment Variables (Best Practice)

Use environment variables for different environments:

// .env.local (development)
// NEXT_PUBLIC_ANALYTICS_API=https://api-dev.yourcompany.com/analytics
// NEXT_PUBLIC_IPWHOIS_API_KEY=your-ipwho-is-key  // optional, for higher rate limits

// .env.production
// NEXT_PUBLIC_ANALYTICS_API=https://api.yourcompany.com/analytics
// NEXT_PUBLIC_IPWHOIS_API_KEY=your-ipwho-is-key

const analytics = useAnalytics({
  config: {
    apiEndpoint: process.env.NEXT_PUBLIC_ANALYTICS_API || '/api/analytics',
    // Optional: your own ipwho.is API key (use env var; omit for free tier)
    ipGeolocation: {
      apiKey: process.env.NEXT_PUBLIC_IPWHOIS_API_KEY,
      timeout: 5000,
    },
  },
});

Step-by-Step Setup

  1. Set up your backend API endpoint (see Backend Setup below)
  2. Configure the frontend with your backend URL
  3. Test the connection using browser DevTools Network tab

Examples by Framework

React (Create React App)

// src/App.tsx
import { useAnalytics } from 'user-analytics-tracker';

function App() {
  const analytics = useAnalytics({
    config: {
      apiEndpoint: process.env.REACT_APP_ANALYTICS_API || 'https://api.yourcompany.com/analytics',
    },
  });
}

Next.js

// app/layout.tsx or pages/_app.tsx
import { useAnalytics } from 'user-analytics-tracker';

export default function Layout() {
  useAnalytics({
    config: {
      apiEndpoint: process.env.NEXT_PUBLIC_ANALYTICS_API || '/api/analytics',
    },
  });
}

Vite + React

// src/main.tsx
import { useAnalytics } from 'user-analytics-tracker';

function App() {
  useAnalytics({
    config: {
      apiEndpoint: import.meta.env.VITE_ANALYTICS_API || 'https://api.yourcompany.com/analytics',
    },
  });
}

🚀 Quick Start

Basic Usage (React Hook)

import { useAnalytics } from 'user-analytics-tracker';

function MyApp() {
  const { 
    sessionId, 
    deviceInfo, 
    location, 
    trackEvent, 
    trackPageView 
  } = useAnalytics({
    autoSend: true,
    config: {
      // Use your own backend server (full URL)
      apiEndpoint: 'https://api.yourcompany.com/analytics',
      // Or use relative path (same domain)
      // apiEndpoint: '/api/analytics',
    },
  });

  // Track page view on mount
  useEffect(() => {
    trackPageView();
  }, [trackPageView]);

  const handleButtonClick = async () => {
    // Track custom event (Firebase/GA-style)
    await trackEvent('button_click', {
      button_name: 'signup',
      button_location: 'header'
    });
  };

  return (
    <div>
      <p>Device: {deviceInfo?.deviceBrand} {deviceInfo?.deviceModel}</p>
      {/* Connection data from ipwho.is (in customData.ipLocation.connection) */}
      <button onClick={handleButtonClick}>
        Track Click
      </button>
    </div>
  );
}

Standalone Detectors (No React)

import {
  NetworkDetector,
  DeviceDetector,
  AttributionDetector,
  LocationDetector,
} from 'user-analytics-tracker';

// Detect network type
const network = NetworkDetector.detect();
console.log(network.type); // 'wifi' | 'cellular' | 'hotspot' | 'ethernet' | 'unknown'

// Detect device info
const device = await DeviceDetector.detect();
console.log(device.deviceBrand, device.deviceModel);

// Detect attribution (UTM params, referrer, etc.)
const attribution = AttributionDetector.detect();
console.log(attribution.utm_source);

// Detect location (automatic IP-based if no consent, GPS if consent granted)
const location = await LocationDetector.detect();
console.log(location.lat, location.lon);
console.log(location.ip); // Public IP (when using IP-based location)
console.log(location.country, location.city); // Location details

// Or get IP-based location only (no permission needed)
const ipLocation = await LocationDetector.detectIPOnly();
console.log(ipLocation.ip, ipLocation.country, ipLocation.city);

📚 API Reference

React Hook: useAnalytics

The main React hook for analytics tracking.

Parameters

useAnalytics(options?: UseAnalyticsOptions): UseAnalyticsReturn

Options:

interface UseAnalyticsOptions {
  autoSend?: boolean; // Auto-send analytics on mount (default: true)
  config?: Partial<AnalyticsConfig>;
  onReady?: (data: {
    sessionId: string;
    networkInfo: NetworkInfo;
    deviceInfo: DeviceInfo;
    location: LocationInfo;
    attribution: AttributionInfo;
  }) => void; // Callback when data is ready
}

interface AnalyticsConfig {
  apiEndpoint: string;
  // Batching options
  batchSize?: number;        // Events per batch (default: 10)
  batchInterval?: number;    // Flush interval in ms (default: 5000)
  maxQueueSize?: number;     // Max queued events (default: 100)
  // Retry options
  maxRetries?: number;       // Max retry attempts (default: 3)
  retryDelay?: number;       // Initial retry delay in ms (default: 1000)
  // Session options
  sessionTimeout?: number;   // Session timeout in ms (default: 1800000 = 30 min)
  // Logging options
  logLevel?: LogLevel;       // 'silent' | 'error' | 'warn' | 'info' | 'debug' (default: 'warn')
  // Metrics options
  enableMetrics?: boolean;   // Enable metrics collection (default: false)
  // IP Geolocation (ipwho.is) - pass your own API key via env var for higher rate limits
  ipGeolocation?: {
    apiKey?: string;   // Use env var. Do not use in browser if using proxyUrl.
    baseUrl?: string;  // Default: 'https://ipwho.is'. Ignored when proxyUrl is set.
    timeout?: number;  // Default: 5000
    ip?: string;       // When provided (server-side), lookup this IP. Ignored when proxyUrl is set.
    proxyUrl?: string; // For paid users in browser: client calls this; backend calls ipwho.is with API key (key never in client).
  };
  // Existing options
  autoSend?: boolean;
  enableLocation?: boolean;
  enableIPGeolocation?: boolean;
  enableNetworkDetection?: boolean;
  enableDeviceDetection?: boolean;
  enableAttribution?: boolean;
  sessionStoragePrefix?: string;
  localStoragePrefix?: string;
}

Returns

interface UseAnalyticsReturn {
  sessionId: string | null;
  networkInfo: NetworkInfo | null;
  deviceInfo: DeviceInfo | null;
  location: LocationInfo | null;
  attribution: AttributionInfo | null;
  pageVisits: number;
  interactions: number;
  logEvent: (customData?: Record<string, any>) => Promise<void>;
  trackEvent: (eventName: string, parameters?: Record<string, any>) => Promise<void>;
  trackPageView: (pageName?: string, parameters?: Record<string, any>) => Promise<void>;
  incrementInteraction: () => void;
  refresh: () => Promise<{
    net: NetworkInfo;
    dev: DeviceInfo;
    attr: AttributionInfo;
    loc: LocationInfo;
  }>;
}

Detectors

NetworkDetector.detect()

Detects network connection type and quality.

const network = NetworkDetector.detect();
// Returns:
// {
//   type: 'wifi' | 'cellular' | 'hotspot' | 'ethernet' | 'unknown';
//   effectiveType?: string; // '2g', '3g', '4g', etc.
//   downlink?: number; // Mbps
//   rtt?: number; // ms
//   saveData?: boolean;
//   connectionType?: string;
// }

DeviceDetector.detect()

Detects device information (async - uses User-Agent Client Hints).

const device = await DeviceDetector.detect();
// Returns:
// {
//   type: 'mobile' | 'tablet' | 'desktop' | 'unknown';
//   os: string;
//   osVersion: string;
//   browser: string;
//   browserVersion: string;
//   deviceModel: string;
//   deviceBrand: string;
//   screenResolution: string;
//   // ... more fields
// }

LocationDetector.detect()

Detects location (IP-first when no consent, GPS when consent granted). Automatically falls back to IP if GPS fails.

const location = await LocationDetector.detect();
// Returns:
// {
//   lat?: number | null;
//   lon?: number | null;
//   accuracy?: number | null;  // GPS only
//   permission: 'granted' | 'denied' | 'prompt' | 'unsupported';
//   source: 'gps' | 'ip' | 'unknown';
//   ts?: string;
//   // IP-based location includes:
//   ip?: string | null;         // Public IP address
//   country?: string;           // Country name
//   countryCode?: string;       // ISO country code
//   city?: string;              // City name
//   region?: string;            // Region/state
//   timezone?: string;          // Timezone
// }

LocationDetector.detectIPOnly()

Get IP-based location only (fast, automatic, no permission needed).

const location = await LocationDetector.detectIPOnly();
// Returns IP-based location with IP address, country, city, coordinates
// Works immediately without user permission

LocationDetector.detectWithAutoConsent()

Automatically grants consent and tries GPS, falls back to IP if GPS fails.

const location = await LocationDetector.detectWithAutoConsent();
// 1. Automatically grants location consent
// 2. Tries GPS location (if available)
// 3. Falls back to IP-based location if GPS fails/denied/unavailable

getPublicIP()

Get just the public IP address (utility function).

import { getPublicIP } from 'user-analytics-tracker';

const ip = await getPublicIP();
console.log(ip); // "203.0.113.42"

AttributionDetector.detect()

Detects UTM parameters, referrer, and session tracking.

const attribution = AttributionDetector.detect();
// Returns:
// {
//   landingUrl: string;
//   referrerUrl: string | null;
//   referrerDomain: string | null;
//   utm_source?: string | null;
//   utm_medium?: string | null;
//   utm_campaign?: string | null;
//   // ... more UTM fields
//   firstTouch?: Record<string, string | null> | null;
//   lastTouch?: Record<string, string | null> | null;
//   sessionStart?: string | null;
// }

Services

AnalyticsService.configure()

Configure the analytics service with advanced options.

import { AnalyticsService } from 'user-analytics-tracker';

AnalyticsService.configure({
  apiEndpoint: 'https://api.yourcompany.com/analytics',
  batchSize: 20,              // Events per batch (default: 10)
  batchInterval: 10000,       // Flush interval in ms (default: 5000)
  maxQueueSize: 100,          // Max queued events (default: 100)
  maxRetries: 5,              // Max retry attempts (default: 3)
  retryDelay: 2000,           // Initial retry delay in ms (default: 1000)
  sessionTimeout: 1800000,    // Session timeout in ms (default: 30 min)
  logLevel: 'info',           // Logging verbosity (default: 'warn')
  enableMetrics: true,        // Enable metrics collection (default: false)
});

AnalyticsService.trackUserJourney()

Send analytics data to your backend.

import { AnalyticsService } from 'user-analytics-tracker';

// Configure endpoint - use your own server
AnalyticsService.configure({ 
  apiEndpoint: 'https://api.yourcompany.com/analytics' 
});

// Or use relative path (same domain)
// AnalyticsService.configure({ apiEndpoint: '/api/analytics' });

// Track event
await AnalyticsService.trackUserJourney({
  sessionId: 'abc123',
  pageUrl: 'https://example.com/page',
  networkInfo: network,
  deviceInfo: device,
  location: location,
  attribution: attribution,
  customData: { userId: 'user123', action: 'purchase' },
});

AnalyticsService.flushQueue()

Manually flush the event queue (useful before page unload).

// Flush all queued events immediately
await AnalyticsService.flushQueue();

AnalyticsService.getQueueSize()

Get the current number of events in the queue.

const size = AnalyticsService.getQueueSize();
console.log(`Queue has ${size} events`);

AnalyticsService.getMetrics()

Get performance metrics (if enabled).

const metrics = AnalyticsService.getMetrics();
if (metrics) {
  console.log(`Sent: ${metrics.eventsSent}, Failed: ${metrics.eventsFailed}`);
}

Utilities

Logger

Configure logging levels for better debugging and production use.

import { logger } from 'user-analytics-tracker';

// Set log level
logger.setLevel('debug'); // 'silent' | 'error' | 'warn' | 'info' | 'debug'

// Use logger
logger.debug('Debug message');
logger.info('Info message');
logger.warn('Warning message');
logger.error('Error message');

Plugin Manager

Register and manage plugins for event transformation.

import { pluginManager } from 'user-analytics-tracker';

// Register a plugin
pluginManager.register({
  name: 'my-plugin',
  beforeSend: (event) => {
    // Transform event
    return event;
  },
});

// Unregister a plugin
pluginManager.unregister('my-plugin');

// Get all plugins
const plugins = pluginManager.getPlugins();

Queue Manager

Advanced queue management (for power users).

import { QueueManager } from 'user-analytics-tracker';

const queue = new QueueManager({
  batchSize: 20,
  batchInterval: 10000,
  maxQueueSize: 200,
  storageKey: 'my-queue',
});

queue.setFlushCallback(async (events) => {
  // Custom flush logic
});

Metrics Collector

Collect and monitor analytics performance metrics.

import { metricsCollector } from 'user-analytics-tracker';

// Metrics are automatically collected when enableMetrics is true
// Access metrics
const metrics = metricsCollector.getMetrics();

// Reset metrics
metricsCollector.reset();

Location Consent Management

import {
  setLocationConsentGranted,
  hasLocationConsent,
  checkAndSetLocationConsent,
  clearLocationConsent,
} from 'user-analytics-tracker';

// When user enters MSISDN, grant location consent
checkAndSetLocationConsent(msisdn); // Returns true if consent granted

// Check if consent exists
if (hasLocationConsent()) {
  // Location tracking allowed
}

// Manually grant/revoke consent
setLocationConsentGranted();
clearLocationConsent();

Session Management

Enhanced session tracking utilities.

import {
  getOrCreateSession,
  updateSessionActivity,
  getSession,
  clearSession,
} from 'user-analytics-tracker';

// Get or create session with custom timeout (30 minutes)
const session = getOrCreateSession(30 * 60 * 1000);
// Returns: { sessionId, startTime, lastActivity, pageViews }

// Update session activity
updateSessionActivity();

// Get current session
const currentSession = getSession();

// Clear session
clearSession();

Debug Utilities

Development debugging tools.

import { initDebug } from 'user-analytics-tracker';

// Initialize debug tools (automatically called in development)
initDebug();

// Then access via window.__analyticsDebug in browser console

IP Geolocation Utilities

Client-Side: Get Public IP

import { getPublicIP } from 'user-analytics-tracker';

// Get just the public IP address (no location data)
const ip = await getPublicIP();
console.log('Your IP:', ip); // "203.0.113.42"

Server-Side: IP Location from Request

import { getIPLocation, getIPFromRequest } from 'user-analytics-tracker';

// In your API route (Next.js example)
export async function POST(req: Request) {
  const ip = getIPFromRequest(req);

  // Free tier (ipwho.is)
  const location = await getIPLocation(ip);

  // Paid (ipwhois.pro): baseUrl/{IP}?key=API_KEY
  // const location = await getIPLocation(ip, {
  //   baseUrl: 'https://ipwhois.pro',
  //   apiKey: process.env.IPWHOIS_PRO_API_KEY,
  // });
  // location contains: country, region, city, lat, lon, timezone, isp, etc.
}

🔒 Privacy & Consent

MSISDN-Based Consent

When a user enters their phone number (MSISDN), it implies consent for location tracking. The library automatically grants location consent:

import { checkAndSetLocationConsent } from 'user-analytics-tracker';

// When MSISDN is entered
checkAndSetLocationConsent(phoneNumber);
// Location consent is now granted, GPS will be requested automatically

Hotspot Detection & Gating

Detect and restrict hotspot users:

import { useAnalytics } from 'user-analytics-tracker';

// Note: networkInfo is no longer available in essential mode
// Connection data is available in customData.ipLocation.connection from ipwho.is
function ConnectionInfo({ children }) {
  // Connection info comes from ipwho.is API in analytics events
  // Access via: customData.ipLocation.connection (asn, org, isp, domain)
  return children;
}

📖 Advanced Usage

Custom Analytics Service

import { AnalyticsService } from 'user-analytics-tracker';

class MyAnalyticsService extends AnalyticsService {
  static async trackUserJourney(data: any) {
    // Custom tracking logic
    await fetch('/my-custom-endpoint', {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }
}

Custom Event Tracking (Firebase/GA-style)

Track custom events with automatic context collection:

const { trackEvent, trackPageView } = useAnalytics();

// Track button click
await trackEvent('button_click', {
  button_name: 'signup',
  button_location: 'header',
  button_color: 'blue'
});

// Track purchase
await trackEvent('purchase', {
  transaction_id: 'T12345',
  value: 29.99,
  currency: 'USD',
  items: [
    { id: 'item1', name: 'Product 1', price: 29.99 }
  ]
});

// Track page views
await trackPageView('/dashboard', {
  page_title: 'Dashboard',
  user_type: 'premium'
});

// Track current page view
await trackPageView();

Manual Event Tracking (Legacy)

const { logEvent, incrementInteraction } = useAnalytics();

// Log custom event with full control
await logEvent({
  eventType: 'purchase',
  productId: '123',
  amount: 99.99,
});

// Increment interaction counter
incrementInteraction();

Server-Side Integration

Example Next.js API route:

// app/api/analytics/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { getIPFromRequest, getIPLocation } from 'user-analytics-tracker';

export async function POST(req: NextRequest) {
  const body = await req.json();
  const ip = getIPFromRequest(req);
  const ipLocation = await getIPLocation(ip);
  
  // Store analytics with IP location
  await storeAnalytics({
    ...body,
    ip,
    ipLocation,
  });
  
  return NextResponse.json({ ok: true });
}

📚 Documentation

Comprehensive documentation is available in the docs/ directory:

  • Upgrade Guide - Step-by-step migration instructions for upgrading between versions

  • Upgrade Guide - Step-by-step migration instructions for upgrading between versions

    • Breaking changes and compatibility notes
    • New features and improvements
    • Migration examples
    • Troubleshooting upgrade issues
  • Usage Guide - Complete guide on how to use the package in your applications

    • Installation instructions
    • Basic and advanced usage examples
    • React hook documentation
    • Standalone (non-React) usage
    • Framework integrations (Next.js, Gatsby, etc.)
    • Real-world examples
    • Troubleshooting
  • Quick Start Guide - Get started in 5 minutes

    • Installation
    • Basic setup
    • Development workflow
    • Common commands
  • Publishing Guide - How to publish the package

    • Prerequisites
    • Publishing methods (automatic & manual)
    • Version management
    • Best practices
  • Package Structure - Understanding the codebase

    • Directory structure
    • Architecture overview
    • Code organization
    • Development guidelines

🧪 Testing

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

🛠️ Development

# Clone repository
git clone https://github.com/switch-org/analytics-tracker.git
cd analytics-tracker

# Install dependencies
npm install

# Build
npm run build

# Watch mode
npm run build:watch

# Lint
npm run lint

# Format
npm run format

# Type check
npm run type-check

📝 TypeScript

This package is written in TypeScript and provides full type definitions. All exports are fully typed:

import type {
  NetworkInfo,
  DeviceInfo,
  LocationInfo,
  AttributionInfo,
  IPLocation,
  UseAnalyticsReturn,
} from 'user-analytics-tracker';

🤝 Contributing

Contributions are welcome! Please read our contributing guidelines first.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'feat: add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Commit Convention

We follow Conventional Commits:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting, etc.)
  • refactor: Code refactoring
  • test: Adding or updating tests
  • chore: Maintenance tasks

📄 License

MIT © Switch Org

🙏 Acknowledgments

  • Uses ipwho.is for IP geolocation (free/paid). For paid users in the browser, use config.ipGeolocation.proxyUrl so the API key is never exposed; see Field Storage / IP Geolocation.
  • Built with modern web APIs (User-Agent Client Hints, Geolocation API)

Made with ❤️ by ATIF RAFIQUE