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">
|
<div className="flex flex-col gap-4">
|
||||||
<p>Copy the code below and insert it to you website</p>
|
<p>Copy the code below and insert it to you website</p>
|
||||||
<Syntax
|
<Syntax
|
||||||
code={`<script src="https://openpanel.dev/op.js" defer async></script>
|
code={`<script src="https://openpanel.dev/op1.js" defer async></script>
|
||||||
<script>
|
<script>
|
||||||
window.op = window.op || function (...args) { (window.op.q = window.op.q || []).push(args); };
|
window.op = window.op || function (...args) { (window.op.q = window.op.q || []).push(args); };
|
||||||
window.op('ctor', {
|
window.op('ctor', {
|
||||||
@@ -252,13 +252,13 @@ app.listen(3000, () => {
|
|||||||
|
|
||||||
<strong>Create a instance</strong>
|
<strong>Create a instance</strong>
|
||||||
<p>
|
<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!
|
environment. You should omit clientSecret if you use this on web!
|
||||||
</p>
|
</p>
|
||||||
<Syntax
|
<Syntax
|
||||||
code={`import { OpenpanelSdk } from '@openpanel/sdk';
|
code={`import { OpenPanel } from '@openpanel/sdk';
|
||||||
|
|
||||||
const op = new OpenpanelSdk({
|
const op = new OpenPanel({
|
||||||
clientId: '${clientId}',
|
clientId: '${clientId}',
|
||||||
// mostly for backend and apps that can't rely on CORS
|
// mostly for backend and apps that can't rely on CORS
|
||||||
clientSecret: '${clientSecret}',
|
clientSecret: '${clientSecret}',
|
||||||
|
|||||||
@@ -43,4 +43,4 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"prettier": "@openpanel/prettier-config"
|
"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
|
##### Web options
|
||||||
- `clientId` - The client id of your application
|
|
||||||
- `trackScreenViews` - If true, the library will automatically track screen views
|
- `trackScreenViews` - If true, the library will automatically track screen views
|
||||||
- `trackOutgoingLinks` - If true, the library will automatically track outgoing links
|
- `trackOutgoingLinks` - If true, the library will automatically track outgoing links
|
||||||
- `trackAttributes` - If true, the library will automatically track attributes
|
- `trackAttributes` - If true, the library will automatically track attributes
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ export default function App({ Component, pageProps }: AppProps) {
|
|||||||
</Head>
|
</Head>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
<Script
|
<Script
|
||||||
src="https://openpanel.dev/op.js"
|
src="https://openpanel.dev/op1.js"
|
||||||
async
|
async
|
||||||
defer
|
defer
|
||||||
strategy="afterInteractive"
|
strategy="afterInteractive"
|
||||||
|
|||||||
@@ -4,21 +4,22 @@
|
|||||||
"type": "separator",
|
"type": "separator",
|
||||||
"title": "Frameworks"
|
"title": "Frameworks"
|
||||||
},
|
},
|
||||||
"script": "Script",
|
"script": "Web (Script Tag)",
|
||||||
|
"web": "Web (Module)",
|
||||||
"nextjs": "Next.js",
|
"nextjs": "Next.js",
|
||||||
"react": "React",
|
"react": "React",
|
||||||
"react-native": "React-Native",
|
"react-native": "React-Native",
|
||||||
"remix": "Remix",
|
"remix": "Remix",
|
||||||
"vue": "Vue",
|
"vue": "Vue",
|
||||||
"astro": "Astro",
|
"astro": "Astro",
|
||||||
"node": "Node (backend)",
|
"node": "Node",
|
||||||
"express": "Express (backend)",
|
"express": "Express (backend)",
|
||||||
"-- Others": {
|
"-- Others": {
|
||||||
"type": "separator",
|
"type": "separator",
|
||||||
"title": "Others"
|
"title": "Others"
|
||||||
},
|
},
|
||||||
"javascript": "Javascript SDK",
|
"javascript": "JavaScript",
|
||||||
"web": "Web SDK",
|
|
||||||
"api": "API",
|
"api": "API",
|
||||||
"export": "Export"
|
"export": "Export",
|
||||||
}
|
"migration": "Migrations"
|
||||||
|
}
|
||||||
@@ -1,32 +1,144 @@
|
|||||||
import Link from 'next/link';
|
# OpenPanel REST API with cURL
|
||||||
import { Steps, Tabs } from 'nextra/components';
|
|
||||||
|
|
||||||
# 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
|
## 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`).
|
All requests to the OpenPanel API require authentication. You'll need to include your `clientId` and `clientSecret` in the headers of each request.
|
||||||
|
|
||||||
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`.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl 'https://api.openpanel.dev/event' \
|
-H "openpanel-client-id: YOUR_CLIENT_ID" \
|
||||||
-H 'content-type: application/json' \
|
-H "openpanel-client-secret: YOUR_CLIENT_SECRET"
|
||||||
-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"}'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Payload
|
## Usage
|
||||||
|
|
||||||
The payload should be a JSON object with the following fields:
|
### Base URL
|
||||||
|
|
||||||
- `name` (string): The name of the event.
|
All API requests should be made to:
|
||||||
- `properties` (object): The properties of the event.
|
|
||||||
- `timestamp` (string): The timestamp of the event in ISO 8601 format.
|
```
|
||||||
|
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 { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||||
import { PersonalDataWarning } from 'src/components/personal-data-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
|
# Express
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ app.use(
|
|||||||
|
|
||||||
app.get('/sign-up', (req, res) => {
|
app.get('/sign-up', (req, res) => {
|
||||||
// track sign up events
|
// track sign up events
|
||||||
req.op.event('sign-up', {
|
req.op.track('sign-up', {
|
||||||
email: req.body.email,
|
email: req.body.email,
|
||||||
});
|
});
|
||||||
res.send('Hello World');
|
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.
|
- `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.
|
- `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.
|
If `req.op` is not typed you can extend the `Request` interface.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { OpenpanelSdk } from '@openpanel/express';
|
import { OpenPanel } from '@openpanel/express';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace Express {
|
namespace Express {
|
||||||
export interface Request {
|
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';
|
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>
|
<Cards>
|
||||||
<Card
|
<Card
|
||||||
@@ -79,3 +117,7 @@ Create an account on [Openpanel](https://openpanel.dev) and setup your first pro
|
|||||||
{' '}
|
{' '}
|
||||||
</Card>
|
</Card>
|
||||||
</Cards>
|
</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, Tabs, Steps } from 'nextra/components';
|
||||||
import { Callout, Steps, Tabs } from 'nextra/components';
|
|
||||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
|
||||||
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
||||||
|
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
||||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
import WebSdkConfig from 'src/components/web-sdk-config.mdx';
|
||||||
|
|
||||||
# Javascript SDK
|
# 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
|
## Installation
|
||||||
|
|
||||||
<Steps>
|
<Steps>
|
||||||
### Install dependencies
|
### Step 1: Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install @openpanel/sdk
|
npm install @openpanel/sdk
|
||||||
```
|
```
|
||||||
|
|
||||||
### Initialize
|
### Step 2: Initialize
|
||||||
|
|
||||||
```tsx
|
```js filename="op.ts"
|
||||||
import { OpenpanelSdk } from '@openpanel/sdk';
|
import { OpenPanel } from '@openpanel/sdk';
|
||||||
|
|
||||||
const op = new OpenpanelSdk({
|
const op = new OpenPanel({
|
||||||
clientId: '{YOUR_CLIENT_ID}',
|
clientId: 'YOUR_CLIENT_ID',
|
||||||
// mostly for backend and apps that can't rely on CORS
|
trackScreenViews: true,
|
||||||
clientSecret: '{YOUR_CLIENT_SECRET}',
|
trackOutgoingLinks: true,
|
||||||
|
trackAttributes: true,
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Config
|
#### Options
|
||||||
|
|
||||||
- `url` - The url of the openpanel API or your self-hosted instance
|
<CommonSdkConfig />
|
||||||
- `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)
|
|
||||||
|
|
||||||
### Ready!
|
### Step 3: Usage
|
||||||
|
|
||||||
You're now ready to use the library.
|
```js filename="main.ts"
|
||||||
|
import { op } from './op.js';
|
||||||
|
|
||||||
```typescript
|
op.track('my_event', { foo: 'bar' });
|
||||||
// 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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Track event
|
### Tracking Events
|
||||||
|
|
||||||
```typescript
|
You can track events with two different methods: by calling the `op.track( directly or by adding `data-track` attributes to your HTML elements.
|
||||||
op.event('my_event', { foo: 'bar' });
|
|
||||||
|
```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 />
|
op.identify({
|
||||||
|
profileId: '123', // Required
|
||||||
```typescript
|
firstName: 'Joe',
|
||||||
const profileId = '123';
|
lastName: 'Doe',
|
||||||
op.setProfileId(profileId);
|
email: 'joe@doe.com',
|
||||||
```
|
properties: {
|
||||||
|
tier: 'premium',
|
||||||
#### 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
|
### Setting Global Properties
|
||||||
|
|
||||||
Increment a property on the profile.
|
To set properties that will be sent with every event:
|
||||||
|
|
||||||
```typescript
|
```js filename="index.js"
|
||||||
// Increment by 1
|
import { op } from './op.ts'
|
||||||
op.increment('app_opened');
|
|
||||||
|
|
||||||
// Increment by 5
|
op.setGlobalProperties({
|
||||||
op.increment('app_opened', 5);
|
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
|
```js filename="index.js"
|
||||||
// Increment by 1
|
import { op } from './op.ts'
|
||||||
op.decrement('app_opened');
|
|
||||||
|
|
||||||
// Increment by 5
|
op.alias({
|
||||||
op.decrement('app_opened', 5);
|
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.
|
||||||
op.clear();
|
|
||||||
|
```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 { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||||
import { PersonalDataWarning } from 'src/components/personal-data-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
|
# Next.js
|
||||||
|
|
||||||
@@ -22,16 +23,15 @@ pnpm install @openpanel/nextjs
|
|||||||
|
|
||||||
### Initialize
|
### Initialize
|
||||||
|
|
||||||
Add `OpenpanelProvider` to your root layout component.
|
Add `OpenpanelComponent` to your root layout component.
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
import { OpenpanelProvider } from '@openpanel/nextjs';
|
import { OpenpanelComponent } from '@openpanel/nextjs';
|
||||||
|
|
||||||
export default RootLayout({ children }) {
|
export default RootLayout({ children }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<OpenpanelProvider
|
<OpenpanelComponent
|
||||||
url="https://api.openpanel.dev"
|
|
||||||
clientId="your-client-id"
|
clientId="your-client-id"
|
||||||
trackScreenViews={true}
|
trackScreenViews={true}
|
||||||
// trackAttributes={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
|
##### `filter`
|
||||||
import {
|
|
||||||
decrement,
|
|
||||||
increment,
|
|
||||||
setProfile,
|
|
||||||
setProfileId,
|
|
||||||
trackEvent,
|
|
||||||
} from '@openpanel/nextjs';
|
|
||||||
|
|
||||||
// Sends an event with payload foo: bar
|
This options needs to be a stringified function and cannot access any variables outside of the function.
|
||||||
trackEvent('my_event', { foo: 'bar' });
|
|
||||||
|
|
||||||
// Identify with profile id
|
```tsx
|
||||||
setProfileId('123');
|
<OpenpanelComponent
|
||||||
|
clientId="your-client-id"
|
||||||
|
filter={`
|
||||||
|
function filter(event) {
|
||||||
|
return event.name !== 'my_event';
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
// or with additional data
|
To take advantage of typescript you can do the following. _Note `toString`_
|
||||||
setProfile({
|
```tsx /.toString();/
|
||||||
profileId: '123',
|
import { type OpenPanelOptions } from '@openpanel/nextjs';
|
||||||
firstName: 'John',
|
|
||||||
lastName: 'Doe',
|
|
||||||
email: 'john.doe@openpanel.dev',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Increment a property
|
const opFilter = ((event: TrackHandlerPayload) => {
|
||||||
increment('app_opened'); // increment by 1
|
return event.type === 'track' && event.payload.name === 'my_event';
|
||||||
increment('app_opened', 5); // increment by 5
|
}).toString();
|
||||||
|
|
||||||
// Decrement a property
|
<OpenpanelComponent
|
||||||
decrement('app_opened'); // decrement by 1
|
clientId="your-client-id"
|
||||||
decrement('app_opened', 5); // decrement by 5
|
filter={opFilter}
|
||||||
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Track event
|
### Client components
|
||||||
|
|
||||||
<Tabs items={['JS', 'window', 'HTML']}>
|
For client components you can just use the `useOpenPanel` hook.
|
||||||
<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>
|
|
||||||
|
|
||||||
### 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.
|
return <button onClick={() => op.track('my_event', { foo: 'bar' })}>Trigger event</button>
|
||||||
|
|
||||||
<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}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 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
|
```tsx filename="utils/op.ts"
|
||||||
import { setProfile } from '@openpanel/nextjs';
|
import { Openpanel } from '@openpanel/nextjs';
|
||||||
|
|
||||||
const profileId = '123';
|
export const op = new Openpanel({
|
||||||
setProfile({
|
clientId: 'your-client-id',
|
||||||
profileId,
|
clientSecret: 'your-client-secret',
|
||||||
// firstName?: string;
|
});
|
||||||
// lastName?: string;
|
|
||||||
// email?: string;
|
// Now you can use `op` to track events
|
||||||
// avatar?: string;
|
op.track('my_event', { foo: 'bar' });
|
||||||
// properties?: Record<string, unknown>;
|
```
|
||||||
|
|
||||||
|
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
|
For server components you can use the `IdentifyComponent` component which is exported from `@openpanel/nextjs`.
|
||||||
import { SetProfile } 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 (
|
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}
|
{children}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Increment property
|
|
||||||
|
|
||||||
Increment a property on the profile.
|
### Setting Global Properties
|
||||||
|
|
||||||
```typescript
|
To set properties that will be sent with every event:
|
||||||
import { increment } from '@openpanel/nextjs';
|
|
||||||
|
|
||||||
// Increment by 1
|
```js filename="index.js"
|
||||||
increment('app_opened');
|
useOpenPanel().setGlobalProperties({
|
||||||
|
app_version: '1.0.2',
|
||||||
// Increment by 5
|
environment: 'production',
|
||||||
increment('app_opened', 5);
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Decrement property
|
### Creating Aliases
|
||||||
|
|
||||||
Decrement a property on the profile.
|
To create an alias for a user:
|
||||||
|
|
||||||
```typescript
|
```js filename="index.js"
|
||||||
import { decrement } from '@openpanel/nextjs';
|
useOpenPanel().alias({
|
||||||
|
alias: 'a1',
|
||||||
// Increment by 1
|
profileId: '1'
|
||||||
decrement('app_opened');
|
});
|
||||||
|
|
||||||
// Increment by 5
|
|
||||||
decrement('app_opened', 5);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 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.
|
||||||
import { clear } from '@openpanel/nextjs';
|
|
||||||
|
|
||||||
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`
|
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.
|
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
|
```typescript filename="/app/api/op/route.ts"
|
||||||
// file: /app/api/op/[...op]/route.ts
|
import { createNextRouteHandler } from '@openpanel/nextjs/server';
|
||||||
import { createNextRouteHandler } from '@openpanel/nextjs';
|
|
||||||
|
|
||||||
export const { POST } = createNextRouteHandler({
|
export const POST = createNextRouteHandler();
|
||||||
clientId: '{YOUR_CLIENT_ID}',
|
|
||||||
clientSecret: '{YOUR_CLIENT_SECRET}',
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
```tsx {2}
|
||||||
<OpenpanelProvider
|
<OpenpanelComponent
|
||||||
url="/api/op" // <---
|
apiUrl="/api/op"
|
||||||
clientId="your-client-id"
|
clientId="your-client-id"
|
||||||
trackScreenViews={true}
|
trackScreenViews={true}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Callout, Steps, Tabs } from 'nextra/components';
|
|||||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
||||||
import { PersonalDataWarning } from 'src/components/personal-data-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
|
# 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`.
|
We're dependent on `expo-application` for `buildNumber`, `versionNumber` (and `referrer` on android) and `expo-constants` to get the `user-agent`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install @openpanel/react-native
|
npm install @openpanel/react-native
|
||||||
npx expo install --pnpm expo-application expo-constants
|
npx expo install expo-application expo-constants
|
||||||
```
|
```
|
||||||
|
|
||||||
### Initialize
|
### Initialize
|
||||||
@@ -30,40 +30,9 @@ const op = new Openpanel({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 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
|
|
||||||
|
|
||||||
### 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
|
|
||||||
```
|
|
||||||
|
|
||||||
|
<CommonSdkConfig />
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -71,7 +40,7 @@ op.decrement('app_opened', 5); // decrement by 5
|
|||||||
### Track event
|
### Track event
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
op.event('my_event', { foo: 'bar' });
|
op.track('my_event', { foo: 'bar' });
|
||||||
```
|
```
|
||||||
|
|
||||||
### Navigation / Screen views
|
### Navigation / Screen views
|
||||||
@@ -139,65 +108,4 @@ op.event('my_event', { foo: 'bar' });
|
|||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### Identify
|
For more information on how to use the SDK, check out the [Javascript SDK](/docs/javascript#usage).
|
||||||
|
|
||||||
#### 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();
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -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 { 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.
|
Just insert this snippet and replace `YOUR_CLIENT_ID` with your client id.
|
||||||
|
|
||||||
```html
|
```html filename="index.html" /clientId: 'YOUR_CLIENT_ID'/
|
||||||
<script src="https://openpanel.dev/op.js" defer async></script>
|
|
||||||
<script>
|
<script>
|
||||||
window.op =
|
window.op = window.op||function(...args){(window.op.q=window.op.q||[]).push(args);};
|
||||||
window.op ||
|
window.op('init', {
|
||||||
function (...args) {
|
|
||||||
(window.op.q = window.op.q || []).push(args);
|
|
||||||
};
|
|
||||||
window.op('ctor', {
|
|
||||||
clientId: 'YOUR_CLIENT_ID',
|
clientId: 'YOUR_CLIENT_ID',
|
||||||
trackScreenViews: true,
|
trackScreenViews: true,
|
||||||
trackOutgoingLinks: true,
|
trackOutgoingLinks: true,
|
||||||
trackAttributes: true,
|
trackAttributes: true,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<script src="https://openpanel.dev/op1.js" defer async></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Config
|
#### Options
|
||||||
|
|
||||||
<SdkConfig />
|
<CommonSdkConfig />
|
||||||
|
<WebSdkConfig />
|
||||||
|
|
||||||
## Usage
|
## 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']}>
|
```html filename="index.html"
|
||||||
<Tabs.Tab>
|
<button onclick="window.op('track', 'my_event', { foo: 'bar' })">
|
||||||
```javascript
|
Track event
|
||||||
window.op('event', 'my_event', { foo: 'bar' });
|
</button>
|
||||||
```
|
|
||||||
</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);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 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
|
```js filename="main.js"
|
||||||
const profileId = '123';
|
window.op('identify', {
|
||||||
window.op('setProfile', {
|
profileId: '123', // Required
|
||||||
profileId,
|
firstName: 'Joe',
|
||||||
// firstName?: string;
|
lastName: 'Doe',
|
||||||
// lastName?: string;
|
email: 'joe@doe.com',
|
||||||
// email?: string;
|
properties: {
|
||||||
// avatar?: string;
|
tier: 'premium',
|
||||||
// properties?: Record<string, unknown>;
|
},
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Increment property
|
### Setting Global Properties
|
||||||
|
|
||||||
Increment a property on the profile.
|
To set properties that will be sent with every event:
|
||||||
|
|
||||||
```javascript
|
```js filename="main.js"
|
||||||
// Increment by 1
|
window.op('setGlobalProperties', {
|
||||||
window.op('increment', 'app_opened');
|
app_version: '1.0.2',
|
||||||
|
environment: 'production',
|
||||||
// Increment by 5
|
});
|
||||||
window.op('increment', 'app_opened', 5);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Decrement property
|
### Creating Aliases
|
||||||
|
|
||||||
Decrement a property on the profile.
|
To create an alias for a user:
|
||||||
|
|
||||||
```javascript
|
```js filename="main.js"
|
||||||
// Increment by 1
|
window.op('alias', {
|
||||||
window.op('decrement', 'app_opened');
|
alias: 'a1',
|
||||||
|
profileId: '1'
|
||||||
// Increment by 5
|
});
|
||||||
window.op('decrement', 'app_opened', 5);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 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');
|
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
|
### 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 {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
op: {
|
op: {
|
||||||
q?: [string, ...any[]];
|
q?: string[][];
|
||||||
(method: string, ...args: any[]): void;
|
(...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, Tabs, Steps } from 'nextra/components';
|
||||||
import { Callout, Steps, Tabs } from 'nextra/components';
|
|
||||||
import { DeviceIdWarning } from 'src/components/device-id-warning';
|
|
||||||
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
import { PersonalDataWarning } from 'src/components/personal-data-warning';
|
||||||
|
import CommonSdkConfig from 'src/components/common-sdk-config.mdx';
|
||||||
import SdkConfig from 'src/components/sdk-config.mdx';
|
import WebSdkConfig from 'src/components/web-sdk-config.mdx';
|
||||||
|
|
||||||
# Web SDK
|
# 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
|
## Installation
|
||||||
|
|
||||||
<Steps>
|
<Steps>
|
||||||
### Install dependencies
|
### Step 1: Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install @openpanel/web
|
npm install @openpanel/web
|
||||||
```
|
```
|
||||||
|
|
||||||
### Initialize
|
### Step 2: Initialize
|
||||||
|
|
||||||
```tsx
|
```js filename="op.ts"
|
||||||
import { Openpanel } from '@openpanel/web';
|
import { OpenPanel } from '@openpanel/web';
|
||||||
|
|
||||||
const op = new Openpanel({
|
const op = new OpenPanel({
|
||||||
clientId: '{YOUR_CLIENT_ID}',
|
clientId: 'YOUR_CLIENT_ID',
|
||||||
trackScreenViews: true,
|
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
|
op.track('my_event', { foo: 'bar' });
|
||||||
// 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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Track event
|
Refer to the [Javascript SDK](/docs/javascript#usage) for usage instructions.
|
||||||
|
|
||||||
```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();
|
|
||||||
```
|
|
||||||
@@ -3,6 +3,14 @@ import { useRouter } from 'next/router';
|
|||||||
import { useConfig } from 'nextra-theme-docs';
|
import { useConfig } from 'nextra-theme-docs';
|
||||||
|
|
||||||
export default {
|
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: (
|
logo: (
|
||||||
<>
|
<>
|
||||||
<Image
|
<Image
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
'use client';
|
import React from 'react';
|
||||||
|
|
||||||
import React, { useEffect } from 'react';
|
|
||||||
import Script from 'next/script';
|
import Script from 'next/script';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
@@ -14,7 +12,7 @@ import type {
|
|||||||
|
|
||||||
export * from '@openpanel/web';
|
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'> & {
|
type OpenPanelComponentProps = Omit<OpenPanelOptions, 'filter'> & {
|
||||||
profileId?: string;
|
profileId?: string;
|
||||||
|
|||||||
@@ -67,12 +67,13 @@ export type OpenPanelOptions = {
|
|||||||
sdkVersion?: string;
|
sdkVersion?: string;
|
||||||
waitForProfile?: boolean;
|
waitForProfile?: boolean;
|
||||||
filter?: (payload: TrackHandlerPayload) => boolean;
|
filter?: (payload: TrackHandlerPayload) => boolean;
|
||||||
|
disable?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class OpenPanel {
|
export class OpenPanel {
|
||||||
api: Api;
|
api: Api;
|
||||||
profileId?: string;
|
profileId?: string;
|
||||||
global?: Record<string, any>;
|
global?: Record<string, unknown>;
|
||||||
queue: TrackHandlerPayload[] = [];
|
queue: TrackHandlerPayload[] = [];
|
||||||
|
|
||||||
constructor(public options: OpenPanelOptions) {
|
constructor(public options: OpenPanelOptions) {
|
||||||
@@ -94,6 +95,7 @@ export class OpenPanel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// placeholder for future use
|
||||||
init() {
|
init() {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
@@ -104,6 +106,10 @@ export class OpenPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async send(payload: TrackHandlerPayload) {
|
async send(payload: TrackHandlerPayload) {
|
||||||
|
if (this.options.disable) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.options.filter && !this.options.filter(payload)) {
|
if (this.options.filter && !this.options.filter(payload)) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
@@ -115,7 +121,7 @@ export class OpenPanel {
|
|||||||
return this.api.fetch('/track', payload);
|
return this.api.fetch('/track', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
setGlobalProperties(properties: Record<string, any>) {
|
setGlobalProperties(properties: Record<string, unknown>) {
|
||||||
this.global = {
|
this.global = {
|
||||||
...this.global,
|
...this.global,
|
||||||
...properties,
|
...properties,
|
||||||
@@ -179,18 +185,18 @@ export class OpenPanel {
|
|||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.profileId = undefined;
|
this.profileId = undefined;
|
||||||
// session end?
|
// should we force a session end here?
|
||||||
}
|
}
|
||||||
|
|
||||||
flush() {
|
flush() {
|
||||||
this.queue.forEach((item) => {
|
this.queue.forEach((item) => {
|
||||||
this.send({
|
this.send({
|
||||||
...item,
|
...item,
|
||||||
// Not user why ts-expect-error is needed here
|
// Not sure why ts-expect-error is needed here
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
payload: {
|
payload: {
|
||||||
...item.payload,
|
...item.payload,
|
||||||
profileId: this.profileId,
|
profileId: item.payload.profileId ?? this.profileId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import type {
|
|||||||
} from '@openpanel/sdk';
|
} from '@openpanel/sdk';
|
||||||
import { OpenPanel as OpenPanelBase } 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 & {
|
export type OpenPanelOptions = OpenPanelBaseOptions & {
|
||||||
trackOutgoingLinks?: boolean;
|
trackOutgoingLinks?: boolean;
|
||||||
@@ -129,20 +130,20 @@ export class OpenPanel extends OpenPanelBase {
|
|||||||
const target = event.target as HTMLElement;
|
const target = event.target as HTMLElement;
|
||||||
const btn = target.closest('button');
|
const btn = target.closest('button');
|
||||||
const anchor = target.closest('a');
|
const anchor = target.closest('a');
|
||||||
const element = btn?.getAttribute('data-event')
|
const element = btn?.getAttribute('data-track')
|
||||||
? btn
|
? btn
|
||||||
: anchor?.getAttribute('data-event')
|
: anchor?.getAttribute('data-track')
|
||||||
? anchor
|
? anchor
|
||||||
: null;
|
: null;
|
||||||
if (element) {
|
if (element) {
|
||||||
const properties: Record<string, unknown> = {};
|
const properties: Record<string, unknown> = {};
|
||||||
for (const attr of element.attributes) {
|
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-/, ''))] =
|
properties[toCamelCase(attr.name.replace(/^data-/, ''))] =
|
||||||
attr.value;
|
attr.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const name = element.getAttribute('data-event');
|
const name = element.getAttribute('data-track');
|
||||||
if (name) {
|
if (name) {
|
||||||
super.track(name, properties);
|
super.track(name, properties);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { OpenPanel } from './index';
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
fn(...args);
|
fn(...args);
|
||||||
} else {
|
} 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') {
|
if (dependent === '@openpanel/web') {
|
||||||
execSync(
|
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