update docs
This commit is contained in:
committed by
Carl-Gerhard Lindesvärd
parent
2226cb463d
commit
03cee826ff
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@@ -0,0 +1 @@
|
||||
*.mdx
|
||||
@@ -64,7 +64,7 @@ const Instructions = ({ framework, client }: Props) => {
|
||||
<div className="flex flex-col gap-4">
|
||||
<p>Copy the code below and insert it to you website</p>
|
||||
<Syntax
|
||||
code={`<script src="https://openpanel.dev/op.js" defer async></script>
|
||||
code={`<script src="https://openpanel.dev/op1.js" defer async></script>
|
||||
<script>
|
||||
window.op = window.op || function (...args) { (window.op.q = window.op.q || []).push(args); };
|
||||
window.op('ctor', {
|
||||
@@ -252,13 +252,13 @@ app.listen(3000, () => {
|
||||
|
||||
<strong>Create a instance</strong>
|
||||
<p>
|
||||
Create a new instance of OpenpanelSdk. You can use this SDK in any JS
|
||||
Create a new instance of OpenPanel. You can use this SDK in any JS
|
||||
environment. You should omit clientSecret if you use this on web!
|
||||
</p>
|
||||
<Syntax
|
||||
code={`import { OpenpanelSdk } from '@openpanel/sdk';
|
||||
code={`import { OpenPanel } from '@openpanel/sdk';
|
||||
|
||||
const op = new OpenpanelSdk({
|
||||
const op = new OpenPanel({
|
||||
clientId: '${clientId}',
|
||||
// mostly for backend and apps that can't rely on CORS
|
||||
clientSecret: '${clientSecret}',
|
||||
|
||||
@@ -43,4 +43,4 @@
|
||||
]
|
||||
},
|
||||
"prettier": "@openpanel/prettier-config"
|
||||
}
|
||||
}
|
||||
8
apps/docs/src/components/common-sdk-config.mdx
Normal file
8
apps/docs/src/components/common-sdk-config.mdx
Normal file
@@ -0,0 +1,8 @@
|
||||
##### 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
|
||||
@@ -1,5 +1,6 @@
|
||||
- `url` - The url of the openpanel API or your self-hosted instance
|
||||
- `clientId` - The client id of your application
|
||||
##### Web options
|
||||
|
||||
- `trackScreenViews` - If true, the library will automatically track screen views
|
||||
- `trackOutgoingLinks` - If true, the library will automatically track outgoing links
|
||||
- `trackAttributes` - If true, the library will automatically track attributes
|
||||
|
||||
@@ -12,7 +12,7 @@ export default function App({ Component, pageProps }: AppProps) {
|
||||
</Head>
|
||||
<Component {...pageProps} />
|
||||
<Script
|
||||
src="https://openpanel.dev/op.js"
|
||||
src="https://openpanel.dev/op1.js"
|
||||
async
|
||||
defer
|
||||
strategy="afterInteractive"
|
||||
|
||||
@@ -4,21 +4,22 @@
|
||||
"type": "separator",
|
||||
"title": "Frameworks"
|
||||
},
|
||||
"script": "Script",
|
||||
"script": "Web (Script Tag)",
|
||||
"web": "Web (Module)",
|
||||
"nextjs": "Next.js",
|
||||
"react": "React",
|
||||
"react-native": "React-Native",
|
||||
"remix": "Remix",
|
||||
"vue": "Vue",
|
||||
"astro": "Astro",
|
||||
"node": "Node (backend)",
|
||||
"node": "Node",
|
||||
"express": "Express (backend)",
|
||||
"-- Others": {
|
||||
"type": "separator",
|
||||
"title": "Others"
|
||||
},
|
||||
"javascript": "Javascript SDK",
|
||||
"web": "Web SDK",
|
||||
"javascript": "JavaScript",
|
||||
"api": "API",
|
||||
"export": "Export"
|
||||
}
|
||||
"export": "Export",
|
||||
"migration": "Migrations"
|
||||
}
|
||||
@@ -1,32 +1,144 @@
|
||||
import Link from 'next/link';
|
||||
import { Steps, Tabs } from 'nextra/components';
|
||||
# OpenPanel REST API with cURL
|
||||
|
||||
# API
|
||||
This guide demonstrates how to interact with the OpenPanel API using cURL. These examples provide a low-level understanding of the API endpoints and can be useful for testing or for integrations where a full SDK isn't available.
|
||||
|
||||
We'll add more SDKs in the future but you can always use our REST API to send events.
|
||||
## Good to know
|
||||
|
||||
- If you want to track **geo location** you'll need to pass the `ip` property as a header `x-client-ip`
|
||||
- If you want to track **device information** you'll need to pass the `user-agent` property as a header `user-agent`
|
||||
|
||||
## Authentication
|
||||
|
||||
To authenticate with the API, you need to use your `clientId` and `clientSecret` (you can find your clients under Settings -> Clients, create a new client if you don't have one with a `clientSecret`).
|
||||
|
||||
We expect you to send `openpanel-client-id` and `openpanel-client-secret` headers with your requests.
|
||||
|
||||
### Example
|
||||
|
||||
This request will create an event with the name `my_event` and the property `foo` set to `bar` and the timestamp set to `2024-03-28T08:42:54.319Z`.
|
||||
All requests to the OpenPanel API require authentication. You'll need to include your `clientId` and `clientSecret` in the headers of each request.
|
||||
|
||||
```bash
|
||||
curl 'https://api.openpanel.dev/event' \
|
||||
-H 'content-type: application/json' \
|
||||
-H 'openpanel-client-id: CLIENT_ID' \
|
||||
-H 'openpanel-client-secret: CLIENT_SECRET' \
|
||||
--data-raw '{"name":"my_event","properties":{"foo":"bar"},"timestamp":"2024-03-28T08:42:54.319Z"}'
|
||||
-H "openpanel-client-id: YOUR_CLIENT_ID" \
|
||||
-H "openpanel-client-secret: YOUR_CLIENT_SECRET"
|
||||
```
|
||||
|
||||
### Payload
|
||||
## Usage
|
||||
|
||||
The payload should be a JSON object with the following fields:
|
||||
### Base URL
|
||||
|
||||
- `name` (string): The name of the event.
|
||||
- `properties` (object): The properties of the event.
|
||||
- `timestamp` (string): The timestamp of the event in ISO 8601 format.
|
||||
All API requests should be made to:
|
||||
|
||||
```
|
||||
https://api.openpanel.dev
|
||||
```
|
||||
|
||||
### Tracking Events
|
||||
|
||||
To track an event:
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.openpanel.dev/track \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "openpanel-client-id: YOUR_CLIENT_ID" \
|
||||
-H "openpanel-client-secret: YOUR_CLIENT_SECRET" \
|
||||
-d '{
|
||||
"type": "track",
|
||||
"payload": {
|
||||
"name": "my_event",
|
||||
"properties": {
|
||||
"foo": "bar"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Identifying Users
|
||||
|
||||
To identify a user:
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.openpanel.dev/track \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "openpanel-client-id: YOUR_CLIENT_ID" \
|
||||
-H "openpanel-client-secret: YOUR_CLIENT_SECRET" \
|
||||
-d '{
|
||||
"type": "identify",
|
||||
"payload": {
|
||||
"profileId": "123",
|
||||
"firstName": "Joe",
|
||||
"lastName": "Doe",
|
||||
"email": "joe@doe.com",
|
||||
"properties": {
|
||||
"tier": "premium"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Creating Aliases
|
||||
To create an alias for a user:
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.openpanel.dev/track \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "openpanel-client-id: YOUR_CLIENT_ID" \
|
||||
-H "openpanel-client-secret: YOUR_CLIENT_SECRET" \
|
||||
-d '{
|
||||
"type": "alias",
|
||||
"payload": {
|
||||
"profileId": "1",
|
||||
"alias": "a1"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Incrementing Properties
|
||||
To increment a numeric property:
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.openpanel.dev/track \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "openpanel-client-id: YOUR_CLIENT_ID" \
|
||||
-H "openpanel-client-secret: YOUR_CLIENT_SECRET" \
|
||||
-d '{
|
||||
"type": "increment",
|
||||
"payload": {
|
||||
"profileId": "1",
|
||||
"property": "visits",
|
||||
"value": 1
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Decrementing Properties
|
||||
To decrement a numeric property:
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.openpanel.dev/track \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "openpanel-client-id: YOUR_CLIENT_ID" \
|
||||
-H "openpanel-client-secret: YOUR_CLIENT_SECRET" \
|
||||
-d '{
|
||||
"type": "decrement",
|
||||
"payload": {
|
||||
"profileId": "1",
|
||||
"property": "visits",
|
||||
"value": 1
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
The API uses standard HTTP response codes to indicate the success or failure of requests. In case of an error, the response body will contain more information about the error.
|
||||
Example error response:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "Invalid client credentials",
|
||||
"status": 401
|
||||
}
|
||||
```
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
The API implements rate limiting to prevent abuse. If you exceed the rate limit, you'll receive a 429 (Too Many Requests) response. The response will include headers indicating your rate limit status.
|
||||
|
||||
Best Practices
|
||||
1. Always use HTTPS to ensure secure communication.
|
||||
2. Store your clientId and clientSecret securely and never expose them in client-side code.
|
||||
3. Implement proper error handling in your applications.
|
||||
4. Respect rate limits and implement exponential backoff for retries.
|
||||
@@ -3,7 +3,7 @@ import { Callout, Steps, Tabs } from 'nextra/components';
|
||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
||||
|
||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
||||
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
||||
|
||||
# Express
|
||||
|
||||
@@ -43,7 +43,7 @@ app.use(
|
||||
|
||||
app.get('/sign-up', (req, res) => {
|
||||
// track sign up events
|
||||
req.op.event('sign-up', {
|
||||
req.op.track('sign-up', {
|
||||
email: req.body.email,
|
||||
});
|
||||
res.send('Hello World');
|
||||
@@ -54,10 +54,12 @@ app.listen(3000, () => {
|
||||
});
|
||||
```
|
||||
|
||||
### Config
|
||||
### Options
|
||||
|
||||
<CommonSdkConfig />
|
||||
|
||||
#### Express options
|
||||
|
||||
- `clientId` - Your OpenPanel client ID.
|
||||
- `clientSecret` - Your OpenPanel client secret.
|
||||
- `trackRequest` - A function that returns `true` if the request should be tracked.
|
||||
- `getProfileId` - A function that returns the profile ID of the user making the request.
|
||||
|
||||
@@ -66,12 +68,12 @@ app.listen(3000, () => {
|
||||
If `req.op` is not typed you can extend the `Request` interface.
|
||||
|
||||
```ts
|
||||
import { OpenpanelSdk } from '@openpanel/express';
|
||||
import { OpenPanel } from '@openpanel/express';
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
export interface Request {
|
||||
op: OpenpanelSdk;
|
||||
op: OpenPanel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,47 @@
|
||||
import { Card, Cards } from 'nextra/components';
|
||||
import { Callout, Card, Cards } from 'nextra/components';
|
||||
import { BrandLogo } from 'src/components/brand-logo';
|
||||
|
||||
# Get started
|
||||
# Documentation
|
||||
|
||||
Create an account on [Openpanel](https://openpanel.dev) and setup your first project (takes 2 minutes). You will get a `clientId` that you will use to initialize Openpanel in your app.
|
||||
The OpenPanel SDKs provide a set of core methods that allow you to track events, identify users, and more. Here's an overview of the key methods available in the SDKs.
|
||||
|
||||
<Callout>
|
||||
While all OpenPanel SDKs share a common set of core methods, some may have
|
||||
syntax variations or additional methods specific to their environment. This
|
||||
documentation provides an overview of the base methods and available SDKs.
|
||||
</Callout>
|
||||
|
||||
## Core Methods
|
||||
|
||||
### setGlobalProperties
|
||||
|
||||
Sets global properties that will be included with every subsequent event.
|
||||
|
||||
### track
|
||||
|
||||
Tracks a custom event with the given name and optional properties.
|
||||
|
||||
### identify
|
||||
|
||||
Associates the current user with a unique identifier and optional traits.
|
||||
|
||||
### alias
|
||||
|
||||
Creates an alias for a user identifier.
|
||||
|
||||
### increment
|
||||
|
||||
Increments a numeric property for a user.
|
||||
|
||||
### decrement
|
||||
|
||||
Decrements a numeric property for a user.
|
||||
|
||||
### clear
|
||||
|
||||
Clears the current user identifier and ends the session.
|
||||
|
||||
## Official SDKs
|
||||
|
||||
<Cards>
|
||||
<Card
|
||||
@@ -79,3 +117,7 @@ Create an account on [Openpanel](https://openpanel.dev) and setup your first pro
|
||||
{' '}
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Unofficial SDKs
|
||||
|
||||
While not officially supported, the following community-contributed SDKs are available.
|
||||
|
||||
@@ -1,138 +1,141 @@
|
||||
import Link from 'next/link';
|
||||
import { Callout, Steps, Tabs } from 'nextra/components';
|
||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||
import { Callout, Tabs, Steps } from 'nextra/components';
|
||||
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
||||
|
||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
||||
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
||||
import WebSdkConfig from 'src/components/web-sdk-config.mdx';
|
||||
|
||||
# Javascript SDK
|
||||
|
||||
This is the base SDK for Openpanel. All other SDKs/frameworks are built on top of this one.
|
||||
The OpenPanel Web SDK allows you to track user behavior on your website using a simple script tag. This guide provides instructions for installing and using the Web SDK in your project.
|
||||
|
||||
## Installation
|
||||
|
||||
<Steps>
|
||||
### Install dependencies
|
||||
### Step 1: Install
|
||||
|
||||
```bash
|
||||
pnpm install @openpanel/sdk
|
||||
npm install @openpanel/sdk
|
||||
```
|
||||
|
||||
### Initialize
|
||||
### Step 2: Initialize
|
||||
|
||||
```tsx
|
||||
import { OpenpanelSdk } from '@openpanel/sdk';
|
||||
```js filename="op.ts"
|
||||
import { OpenPanel } from '@openpanel/sdk';
|
||||
|
||||
const op = new OpenpanelSdk({
|
||||
clientId: '{YOUR_CLIENT_ID}',
|
||||
// mostly for backend and apps that can't rely on CORS
|
||||
clientSecret: '{YOUR_CLIENT_SECRET}',
|
||||
const op = new OpenPanel({
|
||||
clientId: 'YOUR_CLIENT_ID',
|
||||
trackScreenViews: true,
|
||||
trackOutgoingLinks: true,
|
||||
trackAttributes: true,
|
||||
});
|
||||
```
|
||||
|
||||
#### Config
|
||||
#### Options
|
||||
|
||||
- `url` - 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 (mostly for backend and apps that can't rely on CORS)
|
||||
<CommonSdkConfig />
|
||||
|
||||
### Ready!
|
||||
### Step 3: Usage
|
||||
|
||||
You're now ready to use the library.
|
||||
```js filename="main.ts"
|
||||
import { op } from './op.js';
|
||||
|
||||
```typescript
|
||||
// Sends an event with payload foo: bar
|
||||
op.event('my_event', { foo: 'bar' });
|
||||
|
||||
// Identify with profile id
|
||||
op.setProfileId('123');
|
||||
|
||||
// or with additional data
|
||||
op.setProfile({
|
||||
profileId: '123',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
email: 'john.doe@openpanel.dev',
|
||||
});
|
||||
|
||||
// Increment a property
|
||||
op.increment('app_opened'); // increment by 1
|
||||
op.increment('app_opened', 5); // increment by 5
|
||||
|
||||
// Decrement a property
|
||||
op.decrement('app_opened'); // decrement by 1
|
||||
op.decrement('app_opened', 5); // decrement by 5
|
||||
op.track('my_event', { foo: 'bar' });
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## Usage
|
||||
|
||||
### Track event
|
||||
### Tracking Events
|
||||
|
||||
```typescript
|
||||
op.event('my_event', { foo: 'bar' });
|
||||
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"
|
||||
import { op } from './op.ts';
|
||||
|
||||
op.track('my_event', { foo: 'bar' });
|
||||
```
|
||||
|
||||
### Identify
|
||||
### Identifying Users
|
||||
|
||||
#### Set Profile Id
|
||||
To identify a user, call the `op.identify( method with a unique identifier.
|
||||
|
||||
Keep track of your users by identifying them with a unique id. This is a good features if you have things behind a login and want to track user behavior.
|
||||
```js filename="index.js"
|
||||
import { op } from './op.ts';
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```typescript
|
||||
const profileId = '123';
|
||||
op.setProfileId(profileId);
|
||||
```
|
||||
|
||||
#### Additional data
|
||||
|
||||
This method does the same as `setProfileId` but also allows you to update the profile with additional data.
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```typescript
|
||||
const profileId = '123';
|
||||
op.setProfile({
|
||||
profileId,
|
||||
// firstName?: string;
|
||||
// lastName?: string;
|
||||
// email?: string;
|
||||
// avatar?: string;
|
||||
// properties?: Record<string, unknown>;
|
||||
op.identify({
|
||||
profileId: '123', // Required
|
||||
firstName: 'Joe',
|
||||
lastName: 'Doe',
|
||||
email: 'joe@doe.com',
|
||||
properties: {
|
||||
tier: 'premium',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Increment property
|
||||
### Setting Global Properties
|
||||
|
||||
Increment a property on the profile.
|
||||
To set properties that will be sent with every event:
|
||||
|
||||
```typescript
|
||||
// Increment by 1
|
||||
op.increment('app_opened');
|
||||
```js filename="index.js"
|
||||
import { op } from './op.ts'
|
||||
|
||||
// Increment by 5
|
||||
op.increment('app_opened', 5);
|
||||
op.setGlobalProperties({
|
||||
app_version: '1.0.2',
|
||||
environment: 'production',
|
||||
});
|
||||
```
|
||||
|
||||
#### Decrement property
|
||||
### Creating Aliases
|
||||
|
||||
Decrement a property on the profile.
|
||||
To create an alias for a user:
|
||||
|
||||
```typescript
|
||||
// Increment by 1
|
||||
op.decrement('app_opened');
|
||||
```js filename="index.js"
|
||||
import { op } from './op.ts'
|
||||
|
||||
// Increment by 5
|
||||
op.decrement('app_opened', 5);
|
||||
op.alias({
|
||||
alias: 'a1',
|
||||
profileId: '1'
|
||||
});
|
||||
```
|
||||
|
||||
#### Clear / Logout
|
||||
### Incrementing Properties
|
||||
|
||||
Clear the profile id and all the data.
|
||||
To increment a numeric property on a user profile.
|
||||
|
||||
```typescript
|
||||
op.clear();
|
||||
- `value` is the amount to increment the property by. If not provided, the property will be incremented by 1.
|
||||
|
||||
```js filename="index.js"
|
||||
import { op } from './op.ts'
|
||||
|
||||
op.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"
|
||||
import { op } from './op.ts'
|
||||
|
||||
op.decrement({
|
||||
profileId: '1',
|
||||
property: 'visits',
|
||||
value: 1 // optional
|
||||
});
|
||||
```
|
||||
|
||||
### Clearing User Data
|
||||
|
||||
To clear the current user's data:
|
||||
|
||||
```js filename="index.js"
|
||||
import { op } from './op.ts'
|
||||
|
||||
op.clear()
|
||||
```
|
||||
3
apps/docs/src/pages/docs/migration/_meta.json
Normal file
3
apps/docs/src/pages/docs/migration/_meta.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"beta-v1": "Beta to v1"
|
||||
}
|
||||
38
apps/docs/src/pages/docs/migration/beta-v1.mdx
Normal file
38
apps/docs/src/pages/docs/migration/beta-v1.mdx
Normal file
@@ -0,0 +1,38 @@
|
||||
# Migrate from `beta` to `v1`
|
||||
|
||||
We are happy to announce the release of `v1` of the Openpanel SDK. This release includes a lot of improvements and changes to the SDK. This guide will help you migrate from the `beta` version to the `v1` version.
|
||||
|
||||
## General
|
||||
|
||||
The `Openpanel` class is now called `OpenPanel`!
|
||||
|
||||
## Options
|
||||
|
||||
- Renamed: `api` to `apiUrl`
|
||||
- Added: `disabled`
|
||||
- Added: `filter`
|
||||
|
||||
## Methods
|
||||
- Renamed: `event` method is now called `track`
|
||||
- Renamed: `setProfile` and `setProfileId` is now called `identify` (and combined)
|
||||
- Changed: `increment('app_opened', 5)` is now `increment({ name: 'app_opened', value: 5, profileId: '123' })`. So profile ID is now required.
|
||||
- Changed: `decrement('app_opened', 5)` is now `decrement({ name: 'app_opened', value: 5, profileId: '123' })`. So profile ID is now required.
|
||||
- Improved: `screenView` method has 2 arguments now. This change is more aligned with `@openpanel/react-native`.
|
||||
```ts
|
||||
screenView(properties?: TrackProperties): void;
|
||||
screenView(path: string, properties?: TrackProperties): void;
|
||||
|
||||
// Example
|
||||
op.screenView('/home', { title: 'Home' }); // path will be "/home"
|
||||
op.screenView({ title: 'Home' }); // path will be what ever window.location.pathname is
|
||||
```
|
||||
|
||||
## Script tag
|
||||
|
||||
- New: `https://openpanel.dev/op1.js` should be used instead of `op.js` (note the filename)
|
||||
|
||||
## @openpanel/nextjs
|
||||
|
||||
- Renamed: `OpenpanelProvider` to `OpenPanelComponent`
|
||||
- Removed: All exported methods (trackEvent etc). Use the `useOpenPanel` hook instead since these are client tracking only
|
||||
- Moved: `createNextRouteHandler` is moved to `@openpanel/nextjs/server`
|
||||
@@ -3,7 +3,8 @@ import { Callout, Steps, Tabs } from 'nextra/components';
|
||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
||||
|
||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
||||
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
||||
import WebSdkConfig from 'src/components/web-sdk-config.mdx';
|
||||
|
||||
# Next.js
|
||||
|
||||
@@ -22,16 +23,15 @@ pnpm install @openpanel/nextjs
|
||||
|
||||
### Initialize
|
||||
|
||||
Add `OpenpanelProvider` to your root layout component.
|
||||
Add `OpenpanelComponent` to your root layout component.
|
||||
|
||||
```tsx
|
||||
import { OpenpanelProvider } from '@openpanel/nextjs';
|
||||
import { OpenpanelComponent } from '@openpanel/nextjs';
|
||||
|
||||
export default RootLayout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<OpenpanelProvider
|
||||
url="https://api.openpanel.dev"
|
||||
<OpenpanelComponent
|
||||
clientId="your-client-id"
|
||||
trackScreenViews={true}
|
||||
// trackAttributes={true}
|
||||
@@ -45,176 +45,197 @@ export default RootLayout({ children }) {
|
||||
}
|
||||
```
|
||||
|
||||
#### Config
|
||||
#### Options
|
||||
|
||||
<SdkConfig />
|
||||
<CommonSdkConfig />
|
||||
<WebSdkConfig />
|
||||
|
||||
### Ready!
|
||||
##### NextJS options
|
||||
|
||||
You're now ready to use the library.
|
||||
- `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)
|
||||
|
||||
```typescript
|
||||
import {
|
||||
decrement,
|
||||
increment,
|
||||
setProfile,
|
||||
setProfileId,
|
||||
trackEvent,
|
||||
} from '@openpanel/nextjs';
|
||||
##### `filter`
|
||||
|
||||
// Sends an event with payload foo: bar
|
||||
trackEvent('my_event', { foo: 'bar' });
|
||||
This options needs to be a stringified function and cannot access any variables outside of the function.
|
||||
|
||||
// Identify with profile id
|
||||
setProfileId('123');
|
||||
```tsx
|
||||
<OpenpanelComponent
|
||||
clientId="your-client-id"
|
||||
filter={`
|
||||
function filter(event) {
|
||||
return event.name !== 'my_event';
|
||||
}
|
||||
`}
|
||||
/>
|
||||
```
|
||||
|
||||
// or with additional data
|
||||
setProfile({
|
||||
profileId: '123',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
email: 'john.doe@openpanel.dev',
|
||||
});
|
||||
To take advantage of typescript you can do the following. _Note `toString`_
|
||||
```tsx /.toString();/
|
||||
import { type OpenPanelOptions } from '@openpanel/nextjs';
|
||||
|
||||
// Increment a property
|
||||
increment('app_opened'); // increment by 1
|
||||
increment('app_opened', 5); // increment by 5
|
||||
const opFilter = ((event: TrackHandlerPayload) => {
|
||||
return event.type === 'track' && event.payload.name === 'my_event';
|
||||
}).toString();
|
||||
|
||||
// Decrement a property
|
||||
decrement('app_opened'); // decrement by 1
|
||||
decrement('app_opened', 5); // decrement by 5
|
||||
<OpenpanelComponent
|
||||
clientId="your-client-id"
|
||||
filter={opFilter}
|
||||
/>
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## Usage
|
||||
|
||||
### Track event
|
||||
### Client components
|
||||
|
||||
<Tabs items={['JS', 'window', 'HTML']}>
|
||||
<Tabs.Tab>
|
||||
```typescript
|
||||
import { trackEvent } from '@openpanel/nextjs';
|
||||
trackEvent('my_event', { foo: 'bar' });
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
```javascript
|
||||
window.op('event', 'my_event', { foo: 'bar' });
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
For this to work you need to enable `trackAttributes` in the config.
|
||||
```html
|
||||
<button data-event="my_event" data-foo="bar">Track event</button>
|
||||
```
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
For client components you can just use the `useOpenPanel` hook.
|
||||
|
||||
### Identify
|
||||
```tsx
|
||||
import { useOpenPanel } from '@openpanel/nextjs';
|
||||
|
||||
#### Set Profile Id
|
||||
function YourComponent() {
|
||||
const op = useOpenPanel();
|
||||
|
||||
Keep track of your users by identifying them with a unique id. This is a good features if you have things behind a login and want to track user behavior.
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```typescript
|
||||
import { setProfileId } from '@openpanel/nextjs';
|
||||
|
||||
const profileId = '123';
|
||||
setProfileId(profileId);
|
||||
```
|
||||
|
||||
Or if you want to identify the user with a server component.
|
||||
|
||||
```typescript
|
||||
import { SetProfileId } from '@openpanel/nextjs';
|
||||
|
||||
export function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<SetProfileId value={'123'} />
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
return <button onClick={() => op.track('my_event', { foo: 'bar' })}>Trigger event</button>
|
||||
}
|
||||
```
|
||||
|
||||
#### Additional data
|
||||
### Server components
|
||||
|
||||
This method does the same as `setProfileId` but also allows you to update the profile with additional data.
|
||||
Since you can't use hooks in server components, you need to create an instance of the SDK. This is exported from `@openpanel/nextjs`.
|
||||
|
||||
<PersonalDataWarning />
|
||||
<Callout>Remember, your client secret is exposed here so do not use this on client side.</Callout>
|
||||
|
||||
```typescript
|
||||
import { setProfile } from '@openpanel/nextjs';
|
||||
```tsx filename="utils/op.ts"
|
||||
import { Openpanel } from '@openpanel/nextjs';
|
||||
|
||||
const profileId = '123';
|
||||
setProfile({
|
||||
profileId,
|
||||
// firstName?: string;
|
||||
// lastName?: string;
|
||||
// email?: string;
|
||||
// avatar?: string;
|
||||
// properties?: Record<string, unknown>;
|
||||
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/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',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Or if you want to identify the user with a server component.
|
||||
#### For server components
|
||||
|
||||
```typescript
|
||||
import { SetProfile } from '@openpanel/nextjs';
|
||||
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()
|
||||
|
||||
export function Layout({ children }) {
|
||||
return (
|
||||
<>
|
||||
<SetProfile profileId={'12'} firstName={'Joe'} lastName={'Doe'} email={'joe.doe@openpanel.dev'} avatar={'https://image.com'} properties={{...}} />
|
||||
<IdentifyComponent
|
||||
profileId={user.id}
|
||||
firstName={user.firstName}
|
||||
lastName={user.lastName}
|
||||
email={user.email}
|
||||
properties={{
|
||||
tier: 'premium',
|
||||
}}
|
||||
/>
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
#### Increment property
|
||||
|
||||
Increment a property on the profile.
|
||||
### Setting Global Properties
|
||||
|
||||
```typescript
|
||||
import { increment } from '@openpanel/nextjs';
|
||||
To set properties that will be sent with every event:
|
||||
|
||||
// Increment by 1
|
||||
increment('app_opened');
|
||||
|
||||
// Increment by 5
|
||||
increment('app_opened', 5);
|
||||
```js filename="index.js"
|
||||
useOpenPanel().setGlobalProperties({
|
||||
app_version: '1.0.2',
|
||||
environment: 'production',
|
||||
});
|
||||
```
|
||||
|
||||
#### Decrement property
|
||||
### Creating Aliases
|
||||
|
||||
Decrement a property on the profile.
|
||||
To create an alias for a user:
|
||||
|
||||
```typescript
|
||||
import { decrement } from '@openpanel/nextjs';
|
||||
|
||||
// Increment by 1
|
||||
decrement('app_opened');
|
||||
|
||||
// Increment by 5
|
||||
decrement('app_opened', 5);
|
||||
```js filename="index.js"
|
||||
useOpenPanel().alias({
|
||||
alias: 'a1',
|
||||
profileId: '1'
|
||||
});
|
||||
```
|
||||
|
||||
#### Clear / Logout
|
||||
### Incrementing Properties
|
||||
|
||||
Clear the profile id and all the data.
|
||||
To increment a numeric property on a user profile.
|
||||
|
||||
```typescript
|
||||
import { clear } from '@openpanel/nextjs';
|
||||
- `value` is the amount to increment the property by. If not provided, the property will be incremented by 1.
|
||||
|
||||
clear();
|
||||
```js filename="index.js"
|
||||
useOpenPanel().increment({
|
||||
profileId: '1',
|
||||
property: 'visits',
|
||||
value: 1 // optional
|
||||
});
|
||||
```
|
||||
|
||||
## Track server events
|
||||
### 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`
|
||||
|
||||
@@ -256,25 +277,21 @@ export function GET() {
|
||||
}
|
||||
```
|
||||
|
||||
## Proxy events
|
||||
### 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
|
||||
// file: /app/api/op/[...op]/route.ts
|
||||
import { createNextRouteHandler } from '@openpanel/nextjs';
|
||||
```typescript filename="/app/api/op/route.ts"
|
||||
import { createNextRouteHandler } from '@openpanel/nextjs/server';
|
||||
|
||||
export const { POST } = createNextRouteHandler({
|
||||
clientId: '{YOUR_CLIENT_ID}',
|
||||
clientSecret: '{YOUR_CLIENT_SECRET}',
|
||||
});
|
||||
export const POST = createNextRouteHandler();
|
||||
```
|
||||
|
||||
Remember to change the `url` in the `OpenpanelProvider` to your own server.
|
||||
Remember to change the `apiUrl` in the `OpenpanelComponent` to your own server.
|
||||
|
||||
```tsx
|
||||
<OpenpanelProvider
|
||||
url="/api/op" // <---
|
||||
```tsx {2}
|
||||
<OpenpanelComponent
|
||||
apiUrl="/api/op"
|
||||
clientId="your-client-id"
|
||||
trackScreenViews={true}
|
||||
/>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Callout, Steps, Tabs } from 'nextra/components';
|
||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
||||
|
||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
||||
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
||||
|
||||
# React-Native
|
||||
|
||||
@@ -15,8 +15,8 @@ import SdkConfig from 'src/components/sdk-config.mdx';
|
||||
We're dependent on `expo-application` for `buildNumber`, `versionNumber` (and `referrer` on android) and `expo-constants` to get the `user-agent`.
|
||||
|
||||
```bash
|
||||
pnpm install @openpanel/react-native
|
||||
npx expo install --pnpm expo-application expo-constants
|
||||
npm install @openpanel/react-native
|
||||
npx expo install expo-application expo-constants
|
||||
```
|
||||
|
||||
### Initialize
|
||||
@@ -30,40 +30,9 @@ const op = new Openpanel({
|
||||
});
|
||||
```
|
||||
|
||||
#### Config
|
||||
|
||||
- `url` - 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
|
||||
|
||||
### Ready!
|
||||
|
||||
You're now ready to use the library.
|
||||
|
||||
```typescript
|
||||
// Sends an event with payload foo: bar
|
||||
op.event('my_event', { foo: 'bar' });
|
||||
|
||||
// Identify with profile id
|
||||
op.setProfileId('123');
|
||||
|
||||
// or with additional data
|
||||
op.setProfile({
|
||||
profileId: '123',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
email: 'john.doe@openpanel.dev',
|
||||
});
|
||||
|
||||
// Increment a property
|
||||
op.increment('app_opened'); // increment by 1
|
||||
op.increment('app_opened', 5); // increment by 5
|
||||
|
||||
// Decrement a property
|
||||
op.decrement('app_opened'); // decrement by 1
|
||||
op.decrement('app_opened', 5); // decrement by 5
|
||||
```
|
||||
#### Options
|
||||
|
||||
<CommonSdkConfig />
|
||||
</Steps>
|
||||
|
||||
## Usage
|
||||
@@ -71,7 +40,7 @@ op.decrement('app_opened', 5); // decrement by 5
|
||||
### Track event
|
||||
|
||||
```typescript
|
||||
op.event('my_event', { foo: 'bar' });
|
||||
op.track('my_event', { foo: 'bar' });
|
||||
```
|
||||
|
||||
### Navigation / Screen views
|
||||
@@ -139,65 +108,4 @@ op.event('my_event', { foo: 'bar' });
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
### Identify
|
||||
|
||||
#### Set Profile Id
|
||||
|
||||
Keep track of your users by identifying them with a unique id. This is a good features if you have things behind a login and want to track user behavior.
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```typescript
|
||||
const profileId = '123';
|
||||
op.setProfileId(profileId);
|
||||
```
|
||||
|
||||
#### Additional data
|
||||
|
||||
This method does the same as `setProfileId` but also allows you to update the profile with additional data.
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```typescript
|
||||
const profileId = '123';
|
||||
op.setProfile({
|
||||
profileId,
|
||||
// firstName?: string;
|
||||
// lastName?: string;
|
||||
// email?: string;
|
||||
// avatar?: string;
|
||||
// properties?: Record<string, unknown>;
|
||||
});
|
||||
```
|
||||
|
||||
#### Increment property
|
||||
|
||||
Increment a property on the profile.
|
||||
|
||||
```typescript
|
||||
// Increment by 1
|
||||
op.increment('app_opened');
|
||||
|
||||
// Increment by 5
|
||||
op.increment('app_opened', 5);
|
||||
```
|
||||
|
||||
#### Decrement property
|
||||
|
||||
Decrement a property on the profile.
|
||||
|
||||
```typescript
|
||||
// Increment by 1
|
||||
op.decrement('app_opened');
|
||||
|
||||
// Increment by 5
|
||||
op.decrement('app_opened', 5);
|
||||
```
|
||||
|
||||
#### Clear / Logout
|
||||
|
||||
Clear the profile id and all the data.
|
||||
|
||||
```typescript
|
||||
op.clear();
|
||||
```
|
||||
For more information on how to use the SDK, check out the [Javascript SDK](/docs/javascript#usage).
|
||||
|
||||
@@ -1,129 +1,183 @@
|
||||
import { Callout, Tabs } from 'nextra/components';
|
||||
import { Callout, Tabs, Steps } from 'nextra/components';
|
||||
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';
|
||||
|
||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
||||
# Web (Script Tag)
|
||||
|
||||
# Script tag
|
||||
The OpenPanel Web SDK allows you to track user behavior on your website using a simple script tag. This guide provides instructions for installing and using the Web SDK in your project.
|
||||
|
||||
## Installation
|
||||
|
||||
Just insert this snippet and replace `YOUR_CLIENT_ID` with your client id.
|
||||
|
||||
```html
|
||||
<script src="https://openpanel.dev/op.js" defer async></script>
|
||||
```html filename="index.html" /clientId: 'YOUR_CLIENT_ID'/
|
||||
<script>
|
||||
window.op =
|
||||
window.op ||
|
||||
function (...args) {
|
||||
(window.op.q = window.op.q || []).push(args);
|
||||
};
|
||||
window.op('ctor', {
|
||||
window.op = window.op||function(...args){(window.op.q=window.op.q||[]).push(args);};
|
||||
window.op('init', {
|
||||
clientId: 'YOUR_CLIENT_ID',
|
||||
trackScreenViews: true,
|
||||
trackOutgoingLinks: true,
|
||||
trackAttributes: true,
|
||||
});
|
||||
</script>
|
||||
<script src="https://openpanel.dev/op1.js" defer async></script>
|
||||
```
|
||||
|
||||
### Config
|
||||
#### Options
|
||||
|
||||
<SdkConfig />
|
||||
<CommonSdkConfig />
|
||||
<WebSdkConfig />
|
||||
|
||||
## Usage
|
||||
|
||||
You can let the library track screen views, outgoing links and attributes tracking by setting the `trackScreenViews`, `trackOutgoingLinks` and `trackAttributes` options to `true`.
|
||||
### Tracking Events
|
||||
|
||||
### Track event
|
||||
You can track events with two different methods: by calling the `window.op('track')` directly or by adding `data-track` attributes to your HTML elements.
|
||||
|
||||
<Tabs items={['JS', 'HTML']}>
|
||||
<Tabs.Tab>
|
||||
```javascript
|
||||
window.op('event', 'my_event', { foo: 'bar' });
|
||||
```
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab>
|
||||
For this to work you need to enable `trackAttributes` in the config.
|
||||
```html
|
||||
<button data-event="my_event" data-foo="bar">Track event</button>
|
||||
```
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
### Identify
|
||||
|
||||
#### Set Profile Id
|
||||
|
||||
Keep track of your users by identifying them with a unique id. This is a good features if you have things behind a login and want to track user behavior.
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```javascript
|
||||
const profileId = '123';
|
||||
window.op('setProfileId', profileId);
|
||||
```html filename="index.html"
|
||||
<button onclick="window.op('track', 'my_event', { foo: 'bar' })">
|
||||
Track event
|
||||
</button>
|
||||
```
|
||||
|
||||
#### Additional data
|
||||
```html filename="index.html"
|
||||
<button data-track="my_event" data-foo="bar">Track event</button>
|
||||
```
|
||||
|
||||
This method does the same as `setProfileId` but also allows you to update the profile with additional data.
|
||||
### Identifying Users
|
||||
|
||||
<PersonalDataWarning />
|
||||
To identify a user, call the `window.op('identify')` method with a unique identifier.
|
||||
|
||||
```javascript
|
||||
const profileId = '123';
|
||||
window.op('setProfile', {
|
||||
profileId,
|
||||
// firstName?: string;
|
||||
// lastName?: string;
|
||||
// email?: string;
|
||||
// avatar?: string;
|
||||
// properties?: Record<string, unknown>;
|
||||
```js filename="main.js"
|
||||
window.op('identify', {
|
||||
profileId: '123', // Required
|
||||
firstName: 'Joe',
|
||||
lastName: 'Doe',
|
||||
email: 'joe@doe.com',
|
||||
properties: {
|
||||
tier: 'premium',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### Increment property
|
||||
### Setting Global Properties
|
||||
|
||||
Increment a property on the profile.
|
||||
To set properties that will be sent with every event:
|
||||
|
||||
```javascript
|
||||
// Increment by 1
|
||||
window.op('increment', 'app_opened');
|
||||
|
||||
// Increment by 5
|
||||
window.op('increment', 'app_opened', 5);
|
||||
```js filename="main.js"
|
||||
window.op('setGlobalProperties', {
|
||||
app_version: '1.0.2',
|
||||
environment: 'production',
|
||||
});
|
||||
```
|
||||
|
||||
#### Decrement property
|
||||
### Creating Aliases
|
||||
|
||||
Decrement a property on the profile.
|
||||
To create an alias for a user:
|
||||
|
||||
```javascript
|
||||
// Increment by 1
|
||||
window.op('decrement', 'app_opened');
|
||||
|
||||
// Increment by 5
|
||||
window.op('decrement', 'app_opened', 5);
|
||||
```js filename="main.js"
|
||||
window.op('alias', {
|
||||
alias: 'a1',
|
||||
profileId: '1'
|
||||
});
|
||||
```
|
||||
|
||||
#### Clear / Logout
|
||||
### Incrementing Properties
|
||||
|
||||
Clear the profile id and all the data.
|
||||
To increment a numeric property on a user profile.
|
||||
|
||||
```typescript
|
||||
- `value` is the amount to increment the property by. If not provided, the property will be incremented by 1.
|
||||
|
||||
```js filename="main.js"
|
||||
window.op('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="main.js"
|
||||
window.op('decrement', {
|
||||
profileId: '1',
|
||||
property: 'visits',
|
||||
value: 1 // optional
|
||||
});
|
||||
```
|
||||
|
||||
### Clearing User Data
|
||||
|
||||
To clear the current user's data:
|
||||
|
||||
```js filename="main.js"
|
||||
window.op('clear');
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Using the Web SDK with NPM
|
||||
|
||||
<Steps>
|
||||
#### Step 1: Install the SDK
|
||||
|
||||
```bash
|
||||
npm install @openpanel/web
|
||||
```
|
||||
|
||||
#### Step 2: Initialize the SDK
|
||||
|
||||
```js filename="op.js"
|
||||
import { OpenPanel } from '@openpanel/web';
|
||||
|
||||
const op = new OpenPanel({
|
||||
clientId: 'YOUR_CLIENT_ID',
|
||||
trackScreenViews: true,
|
||||
trackOutgoingLinks: true,
|
||||
trackAttributes: true,
|
||||
});
|
||||
```
|
||||
|
||||
#### Step 3: Use the SDK
|
||||
|
||||
```js filename="main.js"
|
||||
import { op } from './op.js';
|
||||
|
||||
op.track('my_event', { foo: 'bar' });
|
||||
```
|
||||
</Steps>
|
||||
|
||||
### Typescript
|
||||
|
||||
Is your IDE mad at you for not using typescript? We got you covered.
|
||||
Getting ts errors when using the SDK? You can add a custom type definition file to your project.
|
||||
|
||||
Add this and it will stop complain about `window.op` not being defined.
|
||||
#### Simple
|
||||
|
||||
```typescript
|
||||
Just paste this code in any of your `.d.ts` files.
|
||||
|
||||
```ts filename="op.d.ts"
|
||||
declare global {
|
||||
interface Window {
|
||||
op: {
|
||||
q?: [string, ...any[]];
|
||||
(method: string, ...args: any[]): void;
|
||||
q?: string[][];
|
||||
(...args: [
|
||||
'init' | 'track' | 'identify' | 'setGlobalProperties' | 'alias' | 'increment' | 'decrement' | 'clear',
|
||||
...any[]
|
||||
]): void;
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Strict typing (from sdk)
|
||||
|
||||
Create a `op.d.ts`file and paste the following code:
|
||||
|
||||
```ts filename="op.d.ts"
|
||||
/// <reference types="@openpanel/web" />
|
||||
```
|
||||
@@ -1,137 +1,48 @@
|
||||
import Link from 'next/link';
|
||||
import { Callout, Steps, Tabs } from 'nextra/components';
|
||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||
import { Callout, Tabs, Steps } from 'nextra/components';
|
||||
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
||||
|
||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
||||
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
||||
import WebSdkConfig from 'src/components/web-sdk-config.mdx';
|
||||
|
||||
# Web SDK
|
||||
|
||||
This is a wrapper of <Link href="/docs/javascript">Javascript SDK</Link>. It's a simple way to use the Openpanel SDK in your web application.
|
||||
The OpenPanel Web SDK allows you to track user behavior on your website using a simple script tag. This guide provides instructions for installing and using the Web SDK in your project.
|
||||
|
||||
## Installation
|
||||
|
||||
<Steps>
|
||||
### Install dependencies
|
||||
### Step 1: Install
|
||||
|
||||
```bash
|
||||
pnpm install @openpanel/web
|
||||
npm install @openpanel/web
|
||||
```
|
||||
|
||||
### Initialize
|
||||
### Step 2: Initialize
|
||||
|
||||
```tsx
|
||||
import { Openpanel } from '@openpanel/web';
|
||||
```js filename="op.ts"
|
||||
import { OpenPanel } from '@openpanel/web';
|
||||
|
||||
const op = new Openpanel({
|
||||
clientId: '{YOUR_CLIENT_ID}',
|
||||
const op = new OpenPanel({
|
||||
clientId: 'YOUR_CLIENT_ID',
|
||||
trackScreenViews: true,
|
||||
// trackAttributes: true,
|
||||
// trackOutgoingLinks: true,
|
||||
trackOutgoingLinks: true,
|
||||
trackAttributes: true,
|
||||
});
|
||||
```
|
||||
|
||||
#### Config
|
||||
#### Options
|
||||
|
||||
<SdkConfig />
|
||||
<CommonSdkConfig />
|
||||
<WebSdkConfig />
|
||||
|
||||
### Ready!
|
||||
### Step 3: Usage
|
||||
|
||||
You're now ready to use the library.
|
||||
```js filename="main.ts"
|
||||
import { op } from './op.js';
|
||||
|
||||
```typescript
|
||||
// Sends an event with payload foo: bar
|
||||
op.event('my_event', { foo: 'bar' });
|
||||
|
||||
// Identify with profile id
|
||||
op.setProfileId('123');
|
||||
|
||||
// or with additional data
|
||||
op.setProfile({
|
||||
profileId: '123',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
email: 'john.doe@openpanel.dev',
|
||||
});
|
||||
|
||||
// Increment a property
|
||||
op.increment('app_opened'); // increment by 1
|
||||
op.increment('app_opened', 5); // increment by 5
|
||||
|
||||
// Decrement a property
|
||||
op.decrement('app_opened'); // decrement by 1
|
||||
op.decrement('app_opened', 5); // decrement by 5
|
||||
op.track('my_event', { foo: 'bar' });
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## Usage
|
||||
|
||||
### Track event
|
||||
|
||||
```typescript
|
||||
op.event('my_event', { foo: 'bar' });
|
||||
```
|
||||
|
||||
### Identify
|
||||
|
||||
#### Set Profile Id
|
||||
|
||||
Keep track of your users by identifying them with a unique id. This is a good features if you have things behind a login and want to track user behavior.
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```typescript
|
||||
const profileId = '123';
|
||||
op.setProfileId(profileId);
|
||||
```
|
||||
|
||||
#### Additional data
|
||||
|
||||
This method does the same as `setProfileId` but also allows you to update the profile with additional data.
|
||||
|
||||
<PersonalDataWarning />
|
||||
|
||||
```typescript
|
||||
const profileId = '123';
|
||||
op.setProfile({
|
||||
profileId,
|
||||
// firstName?: string;
|
||||
// lastName?: string;
|
||||
// email?: string;
|
||||
// avatar?: string;
|
||||
// properties?: Record<string, unknown>;
|
||||
});
|
||||
```
|
||||
|
||||
#### Increment property
|
||||
|
||||
Increment a property on the profile.
|
||||
|
||||
```typescript
|
||||
// Increment by 1
|
||||
op.increment('app_opened');
|
||||
|
||||
// Increment by 5
|
||||
op.increment('app_opened', 5);
|
||||
```
|
||||
|
||||
#### Decrement property
|
||||
|
||||
Decrement a property on the profile.
|
||||
|
||||
```typescript
|
||||
// Increment by 1
|
||||
op.decrement('app_opened');
|
||||
|
||||
// Increment by 5
|
||||
op.decrement('app_opened', 5);
|
||||
```
|
||||
|
||||
#### Clear / Logout
|
||||
|
||||
Clear the profile id and all the data.
|
||||
|
||||
```typescript
|
||||
op.clear();
|
||||
```
|
||||
Refer to the [Javascript SDK](/docs/javascript#usage) for usage instructions.
|
||||
@@ -3,6 +3,14 @@ import { useRouter } from 'next/router';
|
||||
import { useConfig } from 'nextra-theme-docs';
|
||||
|
||||
export default {
|
||||
banner: {
|
||||
key: '1.0-release',
|
||||
text: (
|
||||
<a href="/docs/migration/beta-v1">
|
||||
🎉 We have released v1. Read migration guide if needed!
|
||||
</a>
|
||||
),
|
||||
},
|
||||
logo: (
|
||||
<>
|
||||
<Image
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
'use client';
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import Script from 'next/script';
|
||||
|
||||
import type {
|
||||
@@ -14,7 +12,7 @@ import type {
|
||||
|
||||
export * from '@openpanel/web';
|
||||
|
||||
const CDN_URL = 'https://openpanel.dev/op.js';
|
||||
const CDN_URL = 'https://openpanel.dev/op1.js';
|
||||
|
||||
type OpenPanelComponentProps = Omit<OpenPanelOptions, 'filter'> & {
|
||||
profileId?: string;
|
||||
|
||||
@@ -67,12 +67,13 @@ export type OpenPanelOptions = {
|
||||
sdkVersion?: string;
|
||||
waitForProfile?: boolean;
|
||||
filter?: (payload: TrackHandlerPayload) => boolean;
|
||||
disable?: boolean;
|
||||
};
|
||||
|
||||
export class OpenPanel {
|
||||
api: Api;
|
||||
profileId?: string;
|
||||
global?: Record<string, any>;
|
||||
global?: Record<string, unknown>;
|
||||
queue: TrackHandlerPayload[] = [];
|
||||
|
||||
constructor(public options: OpenPanelOptions) {
|
||||
@@ -94,6 +95,7 @@ export class OpenPanel {
|
||||
});
|
||||
}
|
||||
|
||||
// placeholder for future use
|
||||
init() {
|
||||
// empty
|
||||
}
|
||||
@@ -104,6 +106,10 @@ export class OpenPanel {
|
||||
}
|
||||
|
||||
async send(payload: TrackHandlerPayload) {
|
||||
if (this.options.disable) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (this.options.filter && !this.options.filter(payload)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -115,7 +121,7 @@ export class OpenPanel {
|
||||
return this.api.fetch('/track', payload);
|
||||
}
|
||||
|
||||
setGlobalProperties(properties: Record<string, any>) {
|
||||
setGlobalProperties(properties: Record<string, unknown>) {
|
||||
this.global = {
|
||||
...this.global,
|
||||
...properties,
|
||||
@@ -179,18 +185,18 @@ export class OpenPanel {
|
||||
|
||||
clear() {
|
||||
this.profileId = undefined;
|
||||
// session end?
|
||||
// should we force a session end here?
|
||||
}
|
||||
|
||||
flush() {
|
||||
this.queue.forEach((item) => {
|
||||
this.send({
|
||||
...item,
|
||||
// Not user why ts-expect-error is needed here
|
||||
// Not sure why ts-expect-error is needed here
|
||||
// @ts-expect-error
|
||||
payload: {
|
||||
...item.payload,
|
||||
profileId: this.profileId,
|
||||
profileId: item.payload.profileId ?? this.profileId,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,8 @@ import type {
|
||||
} from '@openpanel/sdk';
|
||||
import { OpenPanel as OpenPanelBase } from '@openpanel/sdk';
|
||||
|
||||
export * from '@openpanel/sdk';
|
||||
export type * from '@openpanel/sdk';
|
||||
export { OpenPanel as OpenPanelBase } from '@openpanel/sdk';
|
||||
|
||||
export type OpenPanelOptions = OpenPanelBaseOptions & {
|
||||
trackOutgoingLinks?: boolean;
|
||||
@@ -129,20 +130,20 @@ export class OpenPanel extends OpenPanelBase {
|
||||
const target = event.target as HTMLElement;
|
||||
const btn = target.closest('button');
|
||||
const anchor = target.closest('a');
|
||||
const element = btn?.getAttribute('data-event')
|
||||
const element = btn?.getAttribute('data-track')
|
||||
? btn
|
||||
: anchor?.getAttribute('data-event')
|
||||
: anchor?.getAttribute('data-track')
|
||||
? anchor
|
||||
: null;
|
||||
if (element) {
|
||||
const properties: Record<string, unknown> = {};
|
||||
for (const attr of element.attributes) {
|
||||
if (attr.name.startsWith('data-') && attr.name !== 'data-event') {
|
||||
if (attr.name.startsWith('data-') && attr.name !== 'data-track') {
|
||||
properties[toCamelCase(attr.name.replace(/^data-/, ''))] =
|
||||
attr.value;
|
||||
}
|
||||
}
|
||||
const name = element.getAttribute('data-event');
|
||||
const name = element.getAttribute('data-track');
|
||||
if (name) {
|
||||
super.track(name, properties);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { OpenPanel } from './index';
|
||||
// @ts-expect-error
|
||||
fn(...args);
|
||||
} else {
|
||||
console.warn(`op.js: ${t} is not a function`);
|
||||
console.warn(`OpenPanel: ${t} is not a function`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ function main() {
|
||||
|
||||
if (dependent === '@openpanel/web') {
|
||||
execSync(
|
||||
`cp ${workspacePath('packages/sdks/web/dist/src/tracker.global.js')} ${workspacePath('./apps/public/public/tracker.js')}`
|
||||
`cp ${workspacePath('packages/sdks/web/dist/src/tracker.global.js')} ${workspacePath('./apps/public/public/op1.js')}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user