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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@adopture/next

v0.2.12

Published

Next.js SDK for Adopture feature adoption tracking with SSR support

Downloads

56

Readme

@adopture/next

Next.js SDK for Adopture feature adoption tracking with full SSR support, client/server components, and edge runtime compatibility.

Features

  • 🚀 Full Next.js 15+ support - Works with App Router and Pages Router
  • 🔄 SSR/SSG compatible - Server-side rendering and static generation support
  • 🎯 Client/Server separation - Clean separation with @adopture/next and @adopture/next/server
  • Edge runtime support - Works in middleware and edge functions
  • 🪝 React hooks - Easy-to-use hooks for tracking and exposure
  • 📦 Components - Pre-built components for common tracking patterns
  • 🔧 TypeScript first - Full TypeScript support with strict typing
  • 🎭 Web Vitals - Built-in Core Web Vitals tracking
  • 🛡️ Error boundaries - Automatic error tracking with error boundaries

Installation

npm install @adopture/next @adopture/sdk-core
# or
yarn add @adopture/next @adopture/sdk-core
# or  
pnpm add @adopture/next @adopture/sdk-core

Quick Start

App Router Setup

  1. Set up environment variables (.env.local):
NEXT_PUBLIC_ADOPTURE_API_KEY=ad_live_your_api_key_here
NEXT_PUBLIC_ADOPTURE_API_URL=https://api.adopture.com
  1. Add provider to root layout (app/layout.tsx):
import { AdoptureProvider } from '@adopture/next';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <AdoptureProvider
          config={{
            enableAutoPageTracking: true,
            enableWebVitals: true,
            debug: process.env.NODE_ENV === 'development',
          }}
        >
          {children}
        </AdoptureProvider>
      </body>
    </html>
  );
}
  1. Use in components:
'use client';

import { useAdoptureTracking, AdoptureFeature } from '@adopture/next';

export function MyComponent() {
  const { track, expose, identify } = useAdoptureTracking();

  return (
    <AdoptureFeature featureId="hero-section" trackVisibility>
      <div>
        <h1>Welcome!</h1>
        <button onClick={() => track('cta-click')}>
          Get Started
        </button>
      </div>
    </AdoptureFeature>
  );
}

Pages Router Setup

  1. Add provider to _app.tsx:
import { AdopturePagesProvider } from '@adopture/next';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <AdopturePagesProvider
      config={{
        enableAutoPageTracking: true,
        enableRouteTracking: true,
      }}
    >
      <Component {...pageProps} />
    </AdopturePagesProvider>
  );
}

Server-Side Usage

Server Components

import { initServerTracker } from '@adopture/next/server';

export default async function ServerComponent() {
  const tracker = await initServerTracker();
  
  // Track server-side events
  await tracker.track('server-feature', 'user-123', {
    serverSide: true,
    timestamp: Date.now(),
  });

  return (
    <div>
      <h1>Server Component</h1>
    </div>
  );
}

Server Actions

import { trackFeature, exposeFeature } from '@adopture/next/server';

async function handleSubmit(formData: FormData) {
  'use server';
  
  // Track the form submission
  await trackFeature('form-submit', 'user-123', {
    formType: 'contact',
    fields: formData.size,
  });
  
  // Process the form...
}

API Routes

import { getServerTracker } from '@adopture/next/server';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const tracker = getServerTracker();
  
  try {
    const data = await request.json();
    
    // Track API usage
    await tracker.track('api-endpoint', data.userId, {
      endpoint: '/api/users',
      method: 'POST',
    });
    
    // Process request...
    return NextResponse.json({ success: true });
  } catch (error) {
    // Track errors
    await tracker.track('api-error', 'unknown', {
      endpoint: '/api/users',
      error: error.message,
    });
    
    return NextResponse.json({ error: 'Failed' }, { status: 500 });
  }
}

Middleware Integration

Create middleware.ts in your project root:

import { createAdoptureMiddleware } from '@adopture/next/middleware';

const adoptureMiddleware = createAdoptureMiddleware({
  apiKey: process.env.ADOPTURE_API_KEY!,
  enableRouteTracking: true,
  enablePerformanceTracking: true,
  excludeRoutes: ['/_next/*', '/api/internal/*'],
  userIdExtractor: (request) => {
    // Extract user ID from request
    const authHeader = request.headers.get('authorization');
    return authHeader?.split('Bearer ')[1] || null;
  },
});

export async function middleware(request: NextRequest) {
  return adoptureMiddleware(request);
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};

React Hooks

useAdoptureTracking

Main hook for accessing all tracking functionality:

import { useAdoptureTracking } from '@adopture/next';

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

  useEffect(() => {
    if (isInitialized) {
      expose('my-component', 'mount');
    }
  }, [isInitialized, expose]);

  const handleClick = () => {
    track('button-click', {
      component: 'MyComponent',
      timestamp: Date.now(),
    });
  };

  return <button onClick={handleClick}>Click me</button>;
}

useComponentTracking

Automatically track component lifecycle:

import { useComponentTracking } from '@adopture/next';

function MyComponent() {
  useComponentTracking('my-component', {
    trackMount: true,
    trackUnmount: true,
    metadata: { version: '1.0' },
  });

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

useVisibilityTracking

Track when elements become visible:

import { useVisibilityTracking } from '@adopture/next';

function MyComponent() {
  const visibilityRef = useVisibilityTracking('visible-element', {
    threshold: 0.5,
    trackOnce: true,
  });

  return (
    <div ref={visibilityRef}>
      This will be tracked when 50% visible
    </div>
  );
}

Components

AdoptureFeature

Wrap any content to automatically track exposure and interactions:

import { AdoptureFeature } from '@adopture/next';

function MyPage() {
  return (
    <AdoptureFeature 
      featureId="hero-banner"
      trackVisibility 
      trackInteractions
      visibilityOptions={{ threshold: 0.8 }}
    >
      <div>Your feature content</div>
    </AdoptureFeature>
  );
}

AdoptureTrackClick

Track click events easily:

import { AdoptureTrackClick } from '@adopture/next';

function MyComponent() {
  return (
    <AdoptureTrackClick 
      featureId="cta-button" 
      as="button"
      className="btn-primary"
      metadata={{ location: 'header' }}
    >
      Get Started
    </AdoptureTrackClick>
  );
}

AdoptureErrorBoundary

Automatically track React errors:

import { AdoptureErrorBoundary } from '@adopture/next';

function MyApp() {
  return (
    <AdoptureErrorBoundary 
      featureId="app-boundary"
      fallback={({ error, retry }) => (
        <div>
          <p>Error: {error.message}</p>
          <button onClick={retry}>Retry</button>
        </div>
      )}
    >
      <MyComponent />
    </AdoptureErrorBoundary>
  );
}

Configuration

Client Configuration

const config: NextAdoptureConfig = {
  apiKey: 'ad_live_xxx', // or from NEXT_PUBLIC_ADOPTURE_API_KEY
  apiUrl: 'https://api.adopture.com',
  enableAutoPageTracking: true,
  enableWebVitals: true,
  enableRouteTracking: true,
  disableInDevelopment: false,
  debug: true,
  batchSize: 50,
  flushInterval: 5000,
  visibility: {
    enabled: true,
    threshold: 0.5,
    minDuration: 1000,
  },
};

Server Configuration

const config: ServerAdoptureConfig = {
  apiKey: 'ad_live_xxx', // from ADOPTURE_API_KEY (server-only)
  apiUrl: 'https://api.adopture.com',
  enableEdgeRuntime: true,
  requestTimeout: 5000,
  batchSize: 100,
  flushInterval: 10000,
};

Environment Variables

Client-side (Browser)

  • NEXT_PUBLIC_ADOPTURE_API_KEY - Your Adopture API key
  • NEXT_PUBLIC_ADOPTURE_API_URL - API endpoint (defaults to https://api.adopture.com)
  • NEXT_PUBLIC_ADOPTURE_PROJECT_ID - Project ID (auto-extracted from API key)
  • NEXT_PUBLIC_ADOPTURE_ENVIRONMENT - Environment (live/test)
  • NEXT_PUBLIC_ADOPTURE_DEBUG - Enable debug mode

Server-side

  • ADOPTURE_API_KEY - Server API key (more secure, not sent to client)
  • ADOPTURE_API_URL - API endpoint
  • ADOPTURE_PROJECT_ID - Project ID
  • ADOPTURE_ENVIRONMENT - Environment
  • ADOPTURE_DEBUG - Enable debug mode

SSR Bootstrap Pattern

For optimal SSR performance, bootstrap client-side tracking with server data:

// app/layout.tsx (Server Component)
import { initServerTracker } from '@adopture/next/server';
import { AdoptureBootstrap } from '@adopture/next';

export default async function RootLayout({ children }) {
  const tracker = await initServerTracker();
  const bootstrapData = tracker.generateBootstrapData('user-123', {
    plan: 'pro',
    signupDate: '2024-01-01',
  });

  return (
    <html>
      <head>
        {bootstrapData && <AdoptureBootstrap data={bootstrapData} />}
      </head>
      <body>
        <AdoptureProvider config={{ bootstrapFromServer: true }}>
          {children}  
        </AdoptureProvider>
      </body>
    </html>
  );
}

TypeScript Support

Full TypeScript support with strict typing:

import type { 
  NextAdoptureConfig, 
  NextAdoptureTracker,
  BootstrapData,
  UseAdoptureReturn 
} from '@adopture/next';

const config: NextAdoptureConfig = {
  apiKey: 'ad_live_xxx',
  enableWebVitals: true,
  // Full autocompletion and type checking
};

Best Practices

  1. Use environment variables for configuration
  2. Enable debug mode during development
  3. Use server-side tracking for sensitive operations
  4. Implement error boundaries for robust error tracking
  5. Use visibility tracking for engagement metrics
  6. Bootstrap from server for optimal performance
  7. Exclude internal routes in middleware
  8. Use TypeScript for better developer experience

Examples

Check out the examples directory for complete implementation examples:

API Reference

Client API

  • NextClientTracker - Main client-side tracker class
  • AdoptureProvider - React provider for App Router
  • AdopturePagesProvider - React provider for Pages Router
  • useAdoptureTracking() - Main tracking hook
  • useTrack(), useExpose(), useIdentify() - Specific tracking hooks
  • AdoptureFeature, AdoptureTrackClick - Tracking components

Server API

  • NextServerTracker - Server-side tracker class
  • createServerTracker(), getServerTracker() - Factory functions
  • trackFeature(), exposeFeature() - Server actions
  • createAdoptureMiddleware() - Middleware factory

License

MIT © Adopture