Documentation
SDKs
Next.js

Next.js

Keep in mind that all tracking here happens on the client!

Read more about server side tracking in the Server Side Tracking section.

Installation

Install dependencies

pnpm install @openpanel/nextjs

Initialize

Add OpenPanelComponent to your root layout component.

import { OpenPanelComponent } from '@openpanel/nextjs';
 
export default RootLayout({ children }) {
  return (
    <>
      <OpenPanelComponent
        clientId="your-client-id"
        trackScreenViews={true}
        // trackAttributes={true}
        // trackOutgoingLinks={true}
        // If you have a user id, you can pass it here to identify the user
        // profileId={'123'}
      />
      {children}
    </>
  )
}

Options

Common options
  • apiUrl - The url of the openpanel API or your self-hosted instance
  • clientId - The client id of your application
  • clientSecret - The client secret of your application (only required for server-side events)
  • filter - A function that will be called before sending an event. If it returns false, the event will not be sent
  • disabled - If true, the library will not send any events
  • waitForProfile - If true, the library will wait for the profile to be set before sending events
Web options
  • trackScreenViews - If true, the library will automatically track screen views (default: false)
  • trackOutgoingLinks - If true, the library will automatically track outgoing links (default: false)
  • trackAttributes - If true, you can trigger events by using html attributes (<button type="button" data-track="your_event" />) (default: false)
NextJS options
  • profileId - If you have a user id, you can pass it here to identify the user
  • cdnUrl - The url to the OpenPanel SDK (default: https://openpanel.dev/op1.js)
  • filter - This is a function that will be called before tracking an event. If it returns false the event will not be tracked. Read more
filter

This options needs to be a stringified function and cannot access any variables outside of the function.

<OpenPanelComponent
  clientId="your-client-id"
  filter={`
    function filter(event) {
      return event.name !== 'my_event';
    }
  `}
/>

To take advantage of typescript you can do the following. Note toString

import { type OpenPanelOptions } from '@openpanel/nextjs';
 
const opFilter = ((event: TrackHandlerPayload) => {
  return event.type === 'track' && event.payload.name === 'my_event';
}).toString();
 
<OpenPanelComponent
  clientId="your-client-id"
  filter={opFilter}
/>

Usage

Client components

For client components you can just use the useOpenPanel hook.

import { useOpenPanel } from '@openpanel/nextjs';
 
function YourComponent() {
  const op = useOpenPanel();
 
  return <button type="button" onClick={() => op.track('my_event', { foo: 'bar' })}>Trigger event</button>
}

Server components

Since you can't use hooks in server components, you need to create an instance of the SDK. This is exported from @openpanel/nextjs.

💡
Remember, your client secret is exposed here so do not use this on client side.
utils/op.ts
import { OpenPanel } from '@openpanel/nextjs';
 
export const op = new OpenPanel({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
});
 
// Now you can use `op` to track events
op.track('my_event', { foo: 'bar' });

Refer to the Javascript SDK for usage instructions.

Tracking Events

You can track events with two different methods: by calling the op.track( directly or by adding data-track` attributes to your HTML elements.

index.ts
useOpenPanel().track('my_event', { foo: 'bar' });

Identifying Users

To identify a user, call the `op.identify( method with a unique identifier.

index.js
useOpenPanel().identify({
  profileId: '123', // Required
  firstName: 'Joe',
  lastName: 'Doe',
  email: '[email protected]',
  properties: {
    tier: 'premium',
  },
});

For server components

For server components you can use the IdentifyComponent component which is exported from @openpanel/nextjs.

This component is great if you have the user data available on the server side.

app/nested/layout.tsx
import { IdentifyComponent } from '@openpanel/nextjs';
 
export default function Layout({ children }) {
  const user = await getCurrentUser()
 
  return (
    <>
      <IdentifyComponent
        profileId={user.id}
        firstName={user.firstName}
        lastName={user.lastName}
        email={user.email}
        properties={{
          tier: 'premium',
        }}
      />
      {children}
    </>
  )
}

Setting Global Properties

To set properties that will be sent with every event:

index.js
useOpenPanel().setGlobalProperties({
  app_version: '1.0.2',
  environment: 'production',
});

Creating Aliases

To create an alias for a user:

index.js
useOpenPanel().alias({
  alias: 'a1',
  profileId: '1'
});

Incrementing Properties

To increment a numeric property on a user profile.

  • value is the amount to increment the property by. If not provided, the property will be incremented by 1.
index.js
useOpenPanel().increment({
  profileId: '1',
  property: 'visits',
  value: 1 // optional
});

Decrementing Properties

To decrement a numeric property on a user profile.

  • value is the amount to decrement the property by. If not provided, the property will be decremented by 1.
index.js
useOpenPanel().decrement({
  profileId: '1',
  property: 'visits',
  value: 1 // optional
});

Clearing User Data

To clear the current user's data:

index.js
useOpenPanel().clear()

Server side

If you want to track server-side events, you should create an instance of our Javascript SDK. It's exported from @openpanel/nextjs

💡

When using server events it's important that you use a secret to authenticate the request. This is to prevent unauthorized requests since we cannot use cors headers.

You can use the same clientId but you should pass the associated client secret to the SDK.

import { OpenpanelSdk } from '@openpanel/nextjs';
 
const opServer = new OpenpanelSdk({
  clientId: '{YOUR_CLIENT_ID}',
  clientSecret: '{YOUR_CLIENT_SECRET}',
});
 
opServer.event('my_server_event', { ok: '✅' });
 
// Pass `profileId` to track events for a specific user
opServer.event('my_server_event', { profileId: '123', ok: '✅' });

Serverless & Vercel

If you log events in a serverless environment like Vercel, you can use waitUntil to ensure the event is logged before the function is done.

Otherwise your function might close before the event is logged. Read more about it here (opens in a new tab).

import { waitUntil } from '@vercel/functions';
import { opServer } from 'path/to/your-sdk-instance';
 
export function GET() {
  // Returns a response immediately while keeping the function alive
  waitUntil(opServer.event('my_server_event', { foo: 'bar' }));
  return new Response(`You're event has been logged!`);
}

Proxy events

With createNextRouteHandler you can proxy your events through your server, this will ensure all events are tracked since there is a lot of adblockers that block requests to third party domains.

/app/api/op/route.ts
import { createNextRouteHandler } from '@openpanel/nextjs/server';
 
export const POST = createNextRouteHandler();

Remember to change the apiUrl in the OpenPanelComponent to your own server.

<OpenPanelComponent
  apiUrl="/api/op"
  clientId="your-client-id"
  trackScreenViews={true}
/>