Next.js SDK

First-party Next.js integration for Entrolytics

Next.js SDK

The @entrolytics/nextjs-sdk package provides seamless integration with Next.js 13+ App Router, including Server Components, Client Components, and Middleware support.

Installation

pnpm add @entrolytics/nextjs-sdk

Quick Start

Add Provider

Wrap your app with EntrolyticsProvider:

app/layout.tsx
import { EntrolyticsProvider } from '@entrolytics/nextjs-sdk'

export default function RootLayout({ children }) {
  return (
    <html lang='en'>
      <body>
        <EntrolyticsProvider
          websiteId={process.env.NEXT_PUBLIC_ENTROLYTICS_WEBSITE_ID!}
          host={process.env.NEXT_PUBLIC_ENTROLYTICS_HOST}
          autoTrack={true}
        >
          {children}
        </EntrolyticsProvider>
      </body>
    </html>
  )
}

Add Environment Variables

Create a .env.local file:

.env.local
NEXT_PUBLIC_ENTROLYTICS_WEBSITE_ID=your-website-id
NEXT_PUBLIC_ENTROLYTICS_HOST=https://entrolytics.dev

Track Events

Use the useEntrolytics hook in client components:

app/components/SignupButton.tsx
'use client'

import { useEntrolytics } from '@entrolytics/nextjs-sdk'

export function SignupButton() {
  const { track } = useEntrolytics()

  return (
    <button
      onClick={async () => {
        await track('signup', { plan: 'pro' })
      }}
    >
      Sign Up
    </button>
  )
}

Configuration

EntrolyticsConfig

interface EntrolyticsConfig {
  /** Website ID (required - or use linkId/pixelId) */
  websiteId?: string
  /** Link ID for link tracking */
  linkId?: string
  /** Pixel ID for conversion tracking */
  pixelId?: string
  /** Custom analytics host URL */
  host?: string
  /** Auto-track page views (default: true) */
  autoTrack?: boolean
  /** Use edge runtime endpoints (default: true) */
  useEdgeRuntime?: boolean
  /** Tag for A/B testing */
  tag?: string
  /** Restrict to specific domains */
  domains?: string[]
  /** Strip query params from URLs */
  excludeSearch?: boolean
  /** Strip hash fragments from URLs */
  excludeHash?: boolean
  /** Honor Do Not Track */
  respectDoNotTrack?: boolean
  /** Disable on localhost */
  ignoreLocalhost?: boolean
  /** Transform/cancel events before sending */
  beforeSend?: BeforeSendCallback
  /** Auto-track outbound links */
  trackOutboundLinks?: boolean
  /** Proxy configuration */
  proxy?: ProxyConfig | false
  /** Enable debug logging */
  debug?: boolean
}

Runtime Configuration

The useEdgeRuntime prop controls which collection endpoint is used:

Edge Runtime (default) - Optimized for global distribution:

<EntrolyticsProvider
  websiteId='your-website-id'
  useEdgeRuntime={true} // or omit (default)
>
  {children}
</EntrolyticsProvider>
  • Latency: 50-100ms via edge proxy
  • Best for: Production Next.js applications on Vercel/Netlify
  • Endpoint: Uses /api/send-edge (edge proxy for global distribution)
  • Features: Edge-optimized routing, geo data from provider headers

Node.js Runtime - Direct backend connection:

<EntrolyticsProvider websiteId='your-website-id' useEdgeRuntime={false}>
  {children}
</EntrolyticsProvider>
  • Features: ClickHouse export, MaxMind GeoIP (city-level accuracy)
  • Best for: Self-hosted deployments, custom backend setups
  • Endpoint: Uses /api/send (Node.js runtime)
  • Latency: 50-150ms (regional)

When to use Node.js runtime:

  • Self-hosted Next.js deployments without edge runtime
  • Custom backend configurations
  • Development/testing environments
  • Advanced analytics features (ClickHouse, MaxMind)

See the Intelligent Routing guide for more details.

Tracking Methods

useEntrolytics Hook

'use client'

import { useEntrolytics } from '@entrolytics/nextjs-sdk'

function MyComponent() {
  const {
    track,
    trackView,
    identify,
    trackRevenue,
    trackOutboundLink,
    setTag,
    generateEnhancedIdentity,
    isReady,
    isEnabled,
    config
  } = useEntrolytics()

  // Track event
  await track('button-click')
  await track('button-click', { color: 'blue' })

  // Track page view
  await trackView('/custom-page')

  // Identify user
  await identify('user-123')
  await identify('user-123', { email: 'user@example.com' })

  // Track revenue
  await trackRevenue('purchase', 99.99, 'USD')

  // Track outbound link
  await trackOutboundLink('https://example.com')

  // Set A/B test tag
  setTag('variant-b')

  // Generate enhanced identity
  const identity = generateEnhancedIdentity({
    userId: '123',
    plan: 'pro'
  })
}

Components

TrackEvent Component

Track events declaratively:

import { TrackEvent } from '@entrolytics/nextjs-sdk'
;<TrackEvent
  name='cta-click'
  data={{ location: 'hero' }}
  trigger='click' // or 'visible' or 'submit'
  once={true}
>
  <button>Click Me</button>
</TrackEvent>

Track external link clicks:

import { OutboundLink } from '@entrolytics/nextjs-sdk'
;<OutboundLink href='https://external-site.com' data={{ source: 'sidebar' }}>
  External Link
</OutboundLink>

Script Component

Alternative to Provider (traditional script-based tracking):

app/layout.tsx
import { Script } from '@entrolytics/nextjs-sdk'

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <Script
          websiteId={process.env.NEXT_PUBLIC_ENTROLYTICS_WEBSITE_ID!}
          host={process.env.NEXT_PUBLIC_ENTROLYTICS_HOST}
        />
      </head>
      <body>{children}</body>
    </html>
  )
}

Server-Side Tracking

API Routes

app/api/action/route.ts
import { trackServerEvent } from '@entrolytics/nextjs-sdk/server'

export async function POST(request: Request) {
  await trackServerEvent(
    {
      host: process.env.ENTROLYTICS_HOST!,
      websiteId: process.env.ENTROLYTICS_WEBSITE_ID!
    },
    {
      event: 'api-call',
      data: { endpoint: '/api/action' },
      request
    }
  )

  return Response.json({ success: true })
}

Server Actions

app/actions.ts
'use server'

import { trackServerEvent } from '@entrolytics/nextjs-sdk/server'

export async function createUser(formData: FormData) {
  // Create user logic...
  await trackServerEvent(
    {
      host: process.env.ENTROLYTICS_HOST!,
      websiteId: process.env.ENTROLYTICS_WEBSITE_ID!
    },
    {
      event: 'user-created',
      data: { email: formData.get('email') }
    }
  )
}

Advanced Features

Track link clicks and conversion pixels:

<EntrolyticsProvider
  linkId='link-uuid'
  // OR pixelId="pixel-uuid"
  host={process.env.NEXT_PUBLIC_ENTROLYTICS_HOST}
>
  {children}
</EntrolyticsProvider>

Proxy Configuration

Bypass ad-blockers with proxy mode:

<EntrolyticsProvider
  websiteId='...'
  proxy={{
    enabled: true,
    scriptPath: '/analytics.js',
    collectPath: '/api/collect',
    mode: 'cloak'
  }}
>
  {children}
</EntrolyticsProvider>

Before Send Hook

Transform or cancel events:

<EntrolyticsProvider
  websiteId='...'
  beforeSend={(type, payload) => {
    // Filter out admin users
    if (payload.url?.includes('/admin')) {
      return null // Cancel tracking
    }

    // Add custom data
    return {
      ...payload,
      data: {
        ...payload.data,
        version: '2.0'
      }
    }
  }}
>
  {children}
</EntrolyticsProvider>

Enhanced Identity

Capture detailed browser metadata:

'use client'

import { useEntrolytics } from '@entrolytics/nextjs-sdk'

function ProfilePage() {
  const { identify, generateEnhancedIdentity } = useEntrolytics()

  useEffect(() => {
    const enhanced = generateEnhancedIdentity({
      userId: user.id,
      plan: user.plan
    })

    identify(user.id, enhanced)
  }, [user])
}

Hooks

usePageView

Track page views automatically:

'use client'

import { usePageView } from '@entrolytics/nextjs-sdk'

function PageComponent() {
  usePageView({
    url: '/custom-url',
    enabled: true,
    deps: [searchParams]
  })
}

useWebVitals (Phase 2)

Automatically track Core Web Vitals (LCP, FID, CLS, FCP, TTFB, INP):

'use client'

import { useWebVitals } from '@entrolytics/nextjs-sdk'

function LayoutComponent() {
  // Basic usage - automatically reports all Web Vitals
  useWebVitals()
}

function LayoutWithOptions() {
  // Advanced usage with options
  useWebVitals({
    // Optional: only track specific metrics
    metrics: ['LCP', 'CLS', 'INP'],
    // Optional: callback for each vital measurement
    onVital: (metric) => {
      console.log(`${metric.name}: ${metric.value} (${metric.rating})`)
    },
    // Optional: disable vitals tracking
    enabled: true
  })
}

Note: Requires the optional web-vitals peer dependency:

pnpm add web-vitals

useFormTracking (Phase 2)

Automatically track form interactions and conversions:

'use client'

import { useFormTracking } from '@entrolytics/nextjs-sdk'

function ContactForm() {
  const formRef = useFormTracking({
    formId: 'contact-form',
    // Optional: track specific events
    trackFocus: true,
    trackBlur: true,
    trackChange: true,
    trackSubmit: true,
    trackAbandonment: true
  })

  return (
    <form ref={formRef}>
      <input name='email' type='email' placeholder='Email' />
      <input name='message' type='text' placeholder='Message' />
      <button type='submit'>Send</button>
    </form>
  )
}

Form Events Tracked:

  • focus - When a user focuses on a form field
  • blur - When a user leaves a form field (includes time spent)
  • change - When a field value changes
  • submit - When the form is submitted
  • abandon - When a user leaves the page with an incomplete form

useEventTracker

Create reusable event tracking functions:

'use client'

import { useEventTracker } from '@entrolytics/nextjs-sdk'

function ProductCard({ product }) {
  const trackEvent = useEventTracker()

  return (
    <button
      onClick={() => trackEvent('add_to_cart', { productId: product.id })}
    >
      Add to Cart
    </button>
  )
}

Examples

E-commerce Tracking

'use client'

import { useEntrolytics } from '@entrolytics/nextjs-sdk'

export function ProductPage({ product }) {
  const { track, trackRevenue } = useEntrolytics()

  useEffect(() => {
    track('product-view', {
      productId: product.id,
      category: product.category
    })
  }, [product])

  async function handlePurchase() {
    await trackRevenue('purchase', product.price, 'USD')
  }

  return <button onClick={handlePurchase}>Buy ${product.price}</button>
}

A/B Testing

'use client'

import { useEntrolytics } from '@entrolytics/nextjs-sdk'

export function Hero() {
  const { setTag } = useEntrolytics()
  const variant = Math.random() > 0.5 ? 'a' : 'b'

  useEffect(() => {
    setTag(`hero-${variant}`)
  }, [variant])

  return variant === 'a' ? <HeroA /> : <HeroB />
}

TypeScript Support

Full TypeScript support with exported types:

import type {
  EntrolyticsConfig,
  EventData,
  EventPayload,
  TrackedProperties,
  BeforeSendCallback
} from '@entrolytics/nextjs-sdk'

Features

  • ✅ Next.js 13+ App Router support
  • ✅ Server Components & Client Components
  • ✅ Server-side tracking (API routes, Server Actions)
  • ✅ Automatic page view tracking
  • ✅ Declarative event components
  • ✅ Link and pixel tracking support
  • ✅ Proxy mode for ad-blocker bypass
  • ✅ TypeScript-first with full type safety
  • ✅ Zero config required
  • Web Vitals tracking (LCP, FID, CLS, FCP, TTFB, INP)
  • Form analytics (focus, blur, submit, abandonment)

Support