299 lines
7.3 KiB
Plaintext
299 lines
7.3 KiB
Plaintext
import Link from 'next/link';
|
|
import { Callout, Steps, Tabs } from 'nextra/components';
|
|
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
|
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
|
|
|
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
|
import WebSdkConfig from 'src/components/web-sdk-config.mdx';
|
|
|
|
# Next.js
|
|
|
|
Keep in mind that all tracking here happens on the client!
|
|
|
|
Read more about server side tracking in the [Server Side Tracking](#track-server-events) section.
|
|
|
|
## Installation
|
|
|
|
<Steps>
|
|
### Install dependencies
|
|
|
|
```bash
|
|
pnpm install @openpanel/nextjs
|
|
```
|
|
|
|
### Initialize
|
|
|
|
Add `OpenpanelComponent` to your root layout component.
|
|
|
|
```tsx
|
|
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
|
|
|
|
<CommonSdkConfig />
|
|
<WebSdkConfig />
|
|
|
|
##### 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)
|
|
|
|
##### `filter`
|
|
|
|
This options needs to be a stringified function and cannot access any variables outside of the function.
|
|
|
|
```tsx
|
|
<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`_
|
|
```tsx /.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}
|
|
/>
|
|
```
|
|
|
|
</Steps>
|
|
|
|
## Usage
|
|
|
|
### Client components
|
|
|
|
For client components you can just use the `useOpenPanel` hook.
|
|
|
|
```tsx
|
|
import { useOpenPanel } from '@openpanel/nextjs';
|
|
|
|
function YourComponent() {
|
|
const op = useOpenPanel();
|
|
|
|
return <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`.
|
|
|
|
<Callout>Remember, your client secret is exposed here so do not use this on client side.</Callout>
|
|
|
|
```tsx filename="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](/docs/sdks/javascript#usage) 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.
|
|
|
|
```ts filename="index.ts"
|
|
useOpenPanel().track('my_event', { foo: 'bar' });
|
|
```
|
|
|
|
### Identifying Users
|
|
|
|
To identify a user, call the `op.identify( method with a unique identifier.
|
|
|
|
```js filename="index.js"
|
|
useOpenPanel().identify({
|
|
profileId: '123', // Required
|
|
firstName: 'Joe',
|
|
lastName: 'Doe',
|
|
email: 'joe@doe.com',
|
|
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.
|
|
|
|
```tsx filename="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:
|
|
|
|
```js filename="index.js"
|
|
useOpenPanel().setGlobalProperties({
|
|
app_version: '1.0.2',
|
|
environment: 'production',
|
|
});
|
|
```
|
|
|
|
### Creating Aliases
|
|
|
|
To create an alias for a user:
|
|
|
|
```js filename="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.
|
|
|
|
```js filename="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.
|
|
|
|
```js filename="index.js"
|
|
useOpenPanel().decrement({
|
|
profileId: '1',
|
|
property: 'visits',
|
|
value: 1 // optional
|
|
});
|
|
```
|
|
|
|
### Clearing User Data
|
|
|
|
To clear the current user's data:
|
|
|
|
```js filename="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`
|
|
|
|
<Callout>
|
|
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.
|
|
|
|
</Callout>
|
|
|
|
```typescript
|
|
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](https://vercel.com/docs/functions/functions-api-reference#waituntil).
|
|
|
|
```typescript
|
|
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.
|
|
|
|
```typescript filename="/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.
|
|
|
|
```tsx {2}
|
|
<OpenpanelComponent
|
|
apiUrl="/api/op"
|
|
clientId="your-client-id"
|
|
trackScreenViews={true}
|
|
/>
|
|
```
|