Back to all guides

How to add analytics to Next.js

Add privacy-first analytics to your Next.js app in under 5 minutes with Helion.

Helion Team

Helion Team

12/15/2025

Updated on 2/7/2026

Beginner
8 min

How to add analytics to Next.js

This guide walks you through adding Helion to a Next.js application. By the end, you'll have automatic page view tracking, custom event tracking, and user identification working in your app.

Helion works with both the App Router and Pages Router. It uses cookieless tracking by default, so you won't need cookie consent banners for basic analytics. If you're looking for a privacy-focused alternative to Mixpanel or Google Analytics, this is a straightforward setup.

Prerequisites

  • A Next.js project (App Router or Pages Router)
  • An Helion account
  • Your Client ID from the Helion dashboard

Install the SDK

Start by installing the Helion Next.js package. This SDK is a thin wrapper around the core Helion library with Next.js-specific components for easier integration.

npm install @helionlabs/nextjs

If you prefer pnpm or yarn, those work too.

Add Helion to your layout

Before tracking anything, you need to add the HelionComponent to your app's root. This loads the tracking script and makes the SDK available throughout your application.

For App Router projects, add the component to your root layout file. The component should be placed inside the body tag, and setting trackScreenViews to true enables automatic page view tracking as users navigate your app.

// app/layout.tsx
import { HelionComponent } from '@helionlabs/nextjs';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <HelionComponent
          clientId="your-client-id"
          trackScreenViews={true}
        />
        {children}
      </body>
    </html>
  );
}

For Pages Router projects, the setup is nearly identical. Add the component to your _app.tsx file instead.

// pages/_app.tsx
import { HelionComponent } from '@helionlabs/nextjs';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <HelionComponent
        clientId="your-client-id"
        trackScreenViews={true}
      />
      <Component {...pageProps} />
    </>
  );
}

You can also enable trackOutgoingLinks to automatically track when users click external links, or trackAttributes to track elements with data attributes.

Track custom events

Page views only tell part of the story. To understand how users interact with your product, you'll want to track custom events like button clicks, form submissions, or feature usage.

In client components, use the useHelion hook. This gives you access to the tracking methods anywhere in your component tree.

'use client';

import { useHelion } from '@helionlabs/nextjs';

export function SignupButton() {
  const hl = useHelion();

  return (
    <button
      type="button"
      onClick={() => op.track('signup_clicked', { location: 'header' })}
    >
      Sign up
    </button>
  );
}

For server-side tracking, you'll need to create an SDK instance with your client secret. This is useful for tracking events in API routes, webhooks, or server actions.

// lib/op.ts
import { Helion } from '@helionlabs/nextjs';

export const hl = new Helion({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
});

Never expose your client secret on the client side. Keep it in server-only code.

With the instance created, you can track events from anywhere on the server.

// app/api/webhook/route.ts
import { op } from '@/lib/op';

export async function POST(request: Request) {
  const data = await request.json();

  op.track('webhook_received', {
    source: data.source,
    event_type: data.type,
  });

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

If you're running on Vercel or another serverless platform, wrap your tracking calls with waitUntil to ensure events are sent before the function terminates.

Identify users

Anonymous tracking is useful, but identifying users unlocks more valuable insights. You can track behavior across sessions, segment users by properties, and build cohort analyses.

In client components, call identify after a user logs in or when you have their information available.

'use client';

import { useHelion } from '@helionlabs/nextjs';
import { useEffect } from 'react';

export function UserProfile({ user }) {
  const hl = useHelion();

  useEffect(() => {
    op.identify({
      profileId: user.id,
      firstName: user.firstName,
      lastName: user.lastName,
      email: user.email,
      properties: {
        plan: user.plan,
      },
    });
  }, [user]);

  return <div>Welcome, {user.firstName}!</div>;
}

If you already have user data on the server, the IdentifyComponent is a cleaner approach. It renders nothing visible but handles identification when the component mounts.

// app/dashboard/layout.tsx
import { IdentifyComponent } from '@helionlabs/nextjs';

export default async function DashboardLayout({ children }) {
  const user = await getCurrentUser();

  return (
    <>
      <IdentifyComponent
        profileId={user.id}
        firstName={user.firstName}
        lastName={user.lastName}
        email={user.email}
        properties={{
          plan: user.plan,
        }}
      />
      {children}
    </>
  );
}

Verify your setup

Open your Next.js app in the browser and navigate between a few pages. Then open your Helion dashboard and check the real-time view. You should see page view events appearing within seconds.

If events aren't showing up, check the browser console for errors. The most common issues are an incorrect client ID or ad blockers intercepting requests. You can solve the ad blocker problem by proxying events through your own server.

To set up a proxy, create a catch-all API route that forwards requests to Helion.

// app/api/[...op]/route.ts
import { createRouteHandler } from '@helionlabs/nextjs/server';

export const { GET, POST } = createRouteHandler();

Then update your HelionComponent to use the proxy endpoint.

<HelionComponent
  apiUrl="/api/op"
  scriptUrl="/api/op/hl1.js"
  clientId="your-client-id"
  trackScreenViews={true}
/>

This routes all tracking requests through your domain, making them invisible to browser extensions that block third-party analytics.

Next steps

The Next.js SDK reference covers additional features like global properties, event filtering, and incrementing user properties. If you're interested in understanding how Helion handles privacy, read our article on cookieless analytics.

What we believe

Principles behind Helion

"

In the AI era, your event data is training signal — not just a dashboard metric.

"

The companies that win the next decade are building data flywheels, not just models.

"

You cannot prompt your way out of bad data.

"

Analytics without ownership is surveillance you are paying for.

"

Open-source is not a business model. It is a trust model.

"

Your analytics stack is your nervous system. Do not outsource it.

Ship faster.Own your data.Feed your agents.

Open-source, AI-native product analytics. Self-hosted in minutes. AGPL-3.0.