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

@loopkit/react

v1.1.10

Published

React TypeScript wrapper for @loopkit/javascript with built-in auto-tracking and comprehensive TypeScript support

Downloads

10

Readme

LoopKit React SDK

A complete React TypeScript SDK for tracking events, user identification, and behavioral analytics. Built on top of @loopkit/javascript with full TypeScript support and zero-config auto-tracking.

🚀 New in v1.1.0

  • 🔧 Full TypeScript Support: Comprehensive type definitions imported from @loopkit/javascript
  • 📊 Zero-Config Auto Tracking: Leverages built-in page views, clicks, and error tracking
  • 🎯 React-Specific Hooks: Enhanced hooks with React context and lifecycle integration
  • ⚡ Reduced Bundle Size: Eliminates duplicate code by using core SDK types
  • 🔄 Enhanced Error Boundary: React error tracking that complements global error tracking
  • 🌐 Next.js Compatible: Full server-side rendering (SSR) support

Features

  • 🔧 TypeScript Support: Full TypeScript support with comprehensive type definitions from @loopkit/javascript
  • 📊 Auto Event Tracking: Automatic page views, clicks, and error tracking (enabled by default)
  • ⚛️ React Integration: React hooks, context, and error boundaries
  • 👤 User Identification: Identify users and track their journey
  • 👥 Group Analytics: Associate users with organizations/groups
  • 💾 Local Storage: Persist events offline with automatic retry
  • 🌐 Cross-Platform: Works in browsers and React applications
  • 🌐 Next.js Compatible: Full server-side rendering (SSR) support
  • 📦 Multiple Formats: ES modules, CommonJS, UMD builds available

Installation

npm install @loopkit/react

CDN

<script src="https://unpkg.com/@loopkit/react/dist/index.umd.js"></script>

Quick Start

1. Wrap Your App

import React from 'react';
import { LoopKitProvider } from '@loopkit/react';
import App from './App';

function Root() {
  return (
    <LoopKitProvider apiKey="your-api-key-here">
      <App />
    </LoopKitProvider>
  );
}

export default Root;

2. Use the Hook

import React from 'react';
import { useLoopKit } from '@loopkit/react';

function MyComponent() {
  const { track, identify, isInitialized } = useLoopKit();

  const handleClick = async () => {
    await track('button_clicked', { buttonName: 'Subscribe' });
  };

  if (!isInitialized) {
    return <div>Loading analytics...</div>;
  }

  return <button onClick={handleClick}>Subscribe</button>;
}

Next.js Compatibility

The LoopKit React SDK is fully compatible with Next.js App Router and Pages Router with zero hydration mismatches. The SDK uses a proper SSR-compatible pattern that ensures both server and client render identical markup.

Perfect SSR Support: No hydration mismatches or client/server rendering differences
Automatic Browser Detection: LoopKit only initializes on the client after hydration
SEO-Friendly: Children are fully server-rendered for optimal SEO
Zero Configuration: Works out of the box with both App Router and Pages Router

Next.js App Router Example

// app/layout.tsx
import { LoopKitProvider } from '@loopkit/react';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <LoopKitProvider apiKey="your-api-key-here">{children}</LoopKitProvider>
      </body>
    </html>
  );
}
// app/page.tsx
'use client';
import { useLoopKit } from '@loopkit/react';

export default function HomePage() {
  const { track, isInitialized } = useLoopKit();

  const handleClick = () => {
    if (isInitialized) {
      track('homepage_cta_clicked');
    }
  };

  return <button onClick={handleClick}>Get Started</button>;
}

Next.js Pages Router Example

// pages/_app.tsx
import { LoopKitProvider } from '@loopkit/react';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <LoopKitProvider apiKey="your-api-key-here">
      <Component {...pageProps} />
    </LoopKitProvider>
  );
}

SSR Troubleshooting

If you encounter issues, here are common solutions:

Error: "useLoopKitContext must be used within a LoopKitProvider"

This happens when using LoopKit hooks in Server Components. Solution:

// ❌ Server Component - hooks not allowed
export default function ServerPage() {
  const loopkit = useLoopKit(); // Error!
  return <div>Page</div>;
}

// ✅ Client Component - hooks work perfectly
'use client';
export default function ClientPage() {
  const loopkit = useLoopKit(); // Works!
  return <div>Page</div>;
}

// ✅ Or wrap specific parts in Client Components
export default function MixedPage() {
  return (
    <div>
      <h1>Server-rendered heading</h1>
      <ClientTrackingButton />
    </div>
  );
}

Auto-Tracking Features

The React SDK automatically leverages @loopkit/javascript's built-in auto-tracking:

| Feature | Default | Event Type | Description | | ------------------ | ---------- | ----------- | --------------------------------------- | | Page Views | ✅ Enabled | page_view | Automatic page loads and SPA navigation | | Click Tracking | ✅ Enabled | click | Button, link, and element clicks | | Error Tracking | ✅ Enabled | error | JavaScript errors and exceptions |

Zero-Config Example

import { LoopKitProvider } from '@loopkit/react';

function App() {
  return (
    <LoopKitProvider apiKey="your-api-key">
      {/* Auto-tracking starts immediately! */}
      {/* ✅ Page views tracked automatically */}
      {/* ✅ Button clicks tracked automatically */}
      {/* ✅ JavaScript errors tracked automatically */}
      <YourApp />
    </LoopKitProvider>
  );
}

Customizing Auto-Tracking

<LoopKitProvider
  apiKey="your-api-key"
  config={{
    enableAutoCapture: true, // Page view tracking
    enableAutoClickTracking: true, // Click tracking
    enableErrorTracking: true, // Error tracking
    debug: true, // Enable debug logs
  }}
>
  <App />
</LoopKitProvider>

Hooks

useLoopKit()

Main hook providing full SDK functionality:

import { useLoopKit } from '@loopkit/react';

function MyComponent() {
  const {
    // State
    isInitialized,
    isLoading,
    error,

    // Core methods
    track,
    identify,
    group,
    flush,

    // React-specific convenience methods
    trackPageView,
    trackClick,
    trackFormSubmit,
    setUserId,
    setUserProperties,
  } = useLoopKit({
    userId: 'user123',
    autoIdentify: true, // Auto-identify on mount
  });

  return (
    <div>
      {isLoading && <span>Loading...</span>}
      {error && <span>Error: {error.message}</span>}
      {/* Your component */}
    </div>
  );
}

usePageView()

Track page views with React context:

import { usePageView } from '@loopkit/react';

function Page() {
  // Track page view with additional context
  usePageView('dashboard', {
    section: 'analytics',
    user_type: 'premium',
  });

  return <div>Dashboard</div>;
}

useIdentify()

Auto-identify users:

import { useIdentify } from '@loopkit/react';

function UserProfile({ user }) {
  // Auto-identify when user changes
  useIdentify(user?.id, {
    email: user?.email,
    plan: user?.plan,
  });

  return <div>Welcome {user?.name}!</div>;
}

useTrackEvent()

Create reusable event trackers:

import { useTrackEvent } from '@loopkit/react';

function ProductCard({ product }) {
  const trackProductView = useTrackEvent('product_viewed', {
    category: product.category,
    price: product.price,
  });

  useEffect(() => {
    trackProductView({ product_id: product.id });
  }, [product.id, trackProductView]);

  return <div>{product.name}</div>;
}

usePerformanceTracking()

Track React component performance:

import { usePerformanceTracking } from '@loopkit/react';

function ExpensiveComponent() {
  usePerformanceTracking('ExpensiveComponent', {
    trackRenderTime: true,
    trackMounts: true,
    trackUnmounts: true,
  });

  return <div>Heavy component</div>;
}

useRouteTracking()

Track React Router navigation:

import { useRouteTracking } from '@loopkit/react';
import { useLocation, useParams } from 'react-router-dom';

function RoutePage() {
  const location = useLocation();
  const params = useParams();

  useRouteTracking('product-detail', {
    productId: params.id,
    category: params.category,
  });

  return <div>Product Detail</div>;
}

Error Boundary

Automatic React error tracking:

import { LoopKitErrorBoundary } from '@loopkit/react';

function App() {
  return (
    <LoopKitProvider apiKey="your-api-key">
      <LoopKitErrorBoundary
        fallback={<div>Something went wrong!</div>}
        onError={(error, errorInfo) => {
          console.error('React error:', error);
        }}
      >
        <YourApp />
      </LoopKitErrorBoundary>
    </LoopKitProvider>
  );
}

TypeScript Support

Full TypeScript support with types from @loopkit/javascript:

import type {
  // Core types from @loopkit/javascript
  LoopKitConfig,
  TrackEvent,
  IdentifyEvent,
  GroupEvent,
  TrackOptions,
  ClickEventProperties,
  BatchEventInput,

  // React-specific types
  UserProperties,
  GroupProperties,
  UseLoopKitReturn,
} from '@loopkit/react';

const config: LoopKitConfig = {
  apiKey: 'your-key',
  enableAutoCapture: true,
  enableAutoClickTracking: true,
  enableErrorTracking: true,
  debug: true,
};

function MyComponent() {
  const loopkit: UseLoopKitReturn = useLoopKit();

  const trackCustomEvent = async () => {
    const properties: Record<string, any> = {
      custom_property: 'value',
      timestamp: new Date().toISOString(),
    };

    await loopkit.track('custom_event', properties);
  };

  return <button onClick={trackCustomEvent}>Track Event</button>;
}

Configuration Options

All configuration options from @loopkit/javascript are supported:

<LoopKitProvider
  apiKey="your-api-key"
  config={{
    // API Settings
    baseURL: 'https://api.loopkit.ai/v1',

    // Batching
    batchSize: 50,
    flushInterval: 30,
    maxQueueSize: 1000,

    // Auto-tracking (all enabled by default)
    enableAutoCapture: true, // Page views
    enableAutoClickTracking: true, // Click events
    enableErrorTracking: true, // JavaScript errors

    // Performance
    enableCompression: true,
    requestTimeout: 10000,

    // Debugging
    debug: true,
    logLevel: 'info',

    // Privacy
    respectDoNotTrack: true,
    enableLocalStorage: true,

    // Callbacks
    onBeforeTrack: (event) => {
      console.log('Tracking:', event);
      return event;
    },
    onAfterTrack: (event, success) => {
      console.log(`Event ${success ? 'sent' : 'failed'}:`, event);
    },
    onError: (error) => {
      console.error('LoopKit error:', error);
    },
  }}
  onError={(error) => console.error('Provider error:', error)}
  onInitialized={() => console.log('LoopKit initialized')}
>
  <App />
</LoopKitProvider>

Advanced Usage

Access the Core SDK

import { LoopKit } from '@loopkit/react';

// Direct access to @loopkit/javascript SDK
LoopKit.track('direct_event', { source: 'direct_sdk' });

Manual Configuration

import { useLoopKitContext } from '@loopkit/react';

function SettingsComponent() {
  const { configure } = useLoopKitContext();

  const updateConfig = () => {
    configure({
      debug: true,
      batchSize: 100,
    });
  };

  return <button onClick={updateConfig}>Enable Debug</button>;
}

Examples

Check out the /examples directory for complete examples:

  • Basic React App: Simple integration example
  • React Router: SPA navigation tracking
  • TypeScript: Full TypeScript implementation
  • Advanced: Performance tracking, error boundaries, custom events

Migration from v1.0.x

v1.1.0 is backward compatible, but you can now:

  1. Remove manual page view tracking - it's automatic now
  2. Remove manual click tracking - it's automatic now
  3. Use TypeScript types from @loopkit/javascript instead of duplicated types
  4. Simplify configuration - auto-tracking is enabled by default

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

License

MIT License. See LICENSE for details.

Next.js Troubleshooting

The latest version (v1.1.9+) has resolved most Next.js compatibility issues. If you encounter issues, here are solutions:

1. ~~"ReactCurrentDispatcher" Error~~ ✅ FIXED

~~If you see an error like Cannot read properties of undefined (reading 'ReactCurrentDispatcher'), this is typically caused by:~~

  • ~~SSR Execution: The SDK trying to execute during server-side rendering~~
  • ✅ RESOLVED: The updated SDK (v1.1.9+) uses a proper SSR-compatible pattern that eliminates hydration mismatches

2. ~~Module Export Errors~~ ✅ FIXED

~~If you see errors like '@loopkit/javascript' does not contain a default export:~~

  • ~~Cause: Module resolution issues between different export formats~~
  • ✅ RESOLVED: The updated SDK (v1.1.9+) handles this automatically with improved import handling

3. ~~"Cannot access before initialization" Errors~~ ✅ IMPROVED

The SDK now safely handles SSR with proper client-side initialization:

// ✅ This now works perfectly - no SSR issues
function MyComponent() {
  const { track, isInitialized } = useLoopKit();

  useEffect(() => {
    if (isInitialized) {
      // Safe to use after initialization
      track('component_mounted');
    }
  }, [isInitialized, track]);

  return <div>My Component</div>;
}

4. App Router vs Pages Router

App Router (Next.js 13+):

  • Use 'use client' directive for components that use LoopKit hooks
  • Place LoopKitProvider in layout.tsx

Pages Router:

  • Place LoopKitProvider in _app.tsx
  • No client directive needed

5. ~~Dynamic Imports (Alternative Approach)~~ ⚠️ NO LONGER NEEDED

~~If you still encounter issues, you can use dynamic imports:~~

Dynamic imports are no longer necessary with v1.1.9+, but if you prefer this approach:

import dynamic from 'next/dynamic';

const AnalyticsProvider = dynamic(
  () =>
    import('@loopkit/react').then((mod) => ({ default: mod.LoopKitProvider })),
  { ssr: false }
);

export default function App({ Component, pageProps }) {
  return (
    <AnalyticsProvider apiKey="your-api-key">
      <Component {...pageProps} />
    </AnalyticsProvider>
  );
}

6. Vercel Deployment Issues

If you encounter build issues on Vercel:

  1. Ensure your package.json includes the correct dependencies
  2. Check that your Node.js version is compatible (16+ recommended)
  3. Consider adding to your next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@loopkit/react', '@loopkit/javascript'],
  experimental: {
    esmExternals: true,
  },
};

module.exports = nextConfig;

Getting Help

If you continue to experience issues:

  1. Check that you're using the latest version: npm update @loopkit/react
  2. Review the Next.js documentation for SSR best practices
  3. Open an issue on the GitHub repository with:
    • Your Next.js version
    • Your @loopkit/react version
    • Full error message and stack trace
    • Minimal reproduction code

Configuration