@splendidlabz/tracking 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/fb/node.js CHANGED
@@ -8,24 +8,71 @@ import {
8
8
  } from './consts.js'
9
9
  import { formatUserData } from './utils.js'
10
10
 
11
- // https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/
11
+ /**
12
+ * Creates a Facebook Conversions API tracker for server-side tracking
13
+ * @param {Object} config - Configuration options
14
+ * @param {string} config.pixelID - Facebook Pixel ID
15
+ * @param {string} [config.testEventCode] - Test event code for debugging
16
+ * @param {string} config.accessToken - Facebook Access Token (required)
17
+ * @param {string} config.framework - Framework being used (astro, express, fastify, koa)
18
+ * @return {Object} FB tracking instance
19
+ * @property {Function} sendEvent - Send a pre-formatted event to CAPI
20
+ * @property {Function} createEvent - Create an event payload
21
+ * @property {Function} track - Track an event and send to CAPI
22
+ * @property {Function} sendCAPIRequest - Send raw request to CAPI
23
+ * @see https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/
24
+ */
12
25
  export default function FB({ pixelID, testEventCode, accessToken, framework }) {
13
26
  framework = framework.toLowerCase()
14
27
 
15
28
  if (!accessToken) throw new Error('Facebook Access Token required')
16
29
 
17
30
  return {
18
- // When used as API call — frontend would have done all the work
19
- // So we can just send the body to the CAPI request
31
+ /**
32
+ * Sends a pre-formatted event to Facebook CAPI
33
+ * Used when frontend has already prepared the event data
34
+ * @param {Object} [props={}] - Event properties including pixel_id, test_event_code, user_data
35
+ * @param {Object} [options={}] - Additional options
36
+ * @param {Object} [options.context] - Framework-specific request context
37
+ * @param {boolean} [options.debug] - Enable debug logging
38
+ * @param {boolean} [options.dryRun] - Skip actual API call
39
+ * @return {Promise<Object>} CAPI response
40
+ */
20
41
  async sendEvent(props = {}, options = {}) {
21
- const { pixel_id, test_event_code, ...rest } = props
42
+ const { pixel_id, test_event_code, user_data, ...rest } = props
43
+ const { context } = options
44
+
45
+ const {
46
+ p: { fbc, fbp },
47
+ o: userProps,
48
+ } = splitObject(user_data, ['fbc', 'fbp'])
49
+
50
+ const data = {
51
+ ...rest,
52
+ user_data: await normalizeUserData({
53
+ context,
54
+ framework,
55
+ userProps,
56
+ fbc,
57
+ fbp,
58
+ }),
59
+ }
60
+
22
61
  const body = {
23
- data: [omitEmpty(rest)],
62
+ data: [omitEmpty(data)],
24
63
  test_event_code: test_event_code || testEventCode,
25
64
  }
26
65
  return this.sendCAPIRequest(body, { ...options, pixel_id })
27
66
  },
28
67
 
68
+ /**
69
+ * Creates a Facebook CAPI event payload
70
+ * @param {string} eventName - Name of the event to track
71
+ * @param {Object} [props={}] - Event properties and user data
72
+ * @param {Object} [props.context] - Framework-specific request context (required for auto-filled properties)
73
+ * @param {Object} [options={}] - Additional options
74
+ * @return {Promise<Object>} Event payload ready to send to CAPI
75
+ */
29
76
  async createEvent(eventName, props = {}, options = {}) {
30
77
  const { context, ...p } = props
31
78
  const { p: eventParams, o: r1 } = splitObject(p, SERVER_EVENT_PARAMS)
@@ -44,8 +91,11 @@ export default function FB({ pixelID, testEventCode, accessToken, framework }) {
44
91
  )
45
92
  }
46
93
 
47
- if (framework !== 'astro') {
48
- throw new Error('Currently we only support the Astro framework')
94
+ const supportedFrameworks = ['astro', 'express', 'fastify', 'koa']
95
+ if (!supportedFrameworks.includes(framework)) {
96
+ throw new Error(
97
+ `Unsupported framework: ${framework}. Supported frameworks: ${supportedFrameworks.join(', ')}`,
98
+ )
49
99
  }
50
100
 
51
101
  const normalizedUserData = await normalizeUserData({
@@ -72,12 +122,32 @@ export default function FB({ pixelID, testEventCode, accessToken, framework }) {
72
122
  return body
73
123
  },
74
124
 
75
- // When used directly via backend
125
+ /**
126
+ * Tracks an event and sends it to Facebook CAPI
127
+ * Combines createEvent and sendCAPIRequest
128
+ * @param {string} eventName - Name of the event to track
129
+ * @param {Object} [props={}] - Event properties and user data
130
+ * @param {Object} [props.context] - Framework-specific request context
131
+ * @param {Object} [options={}] - Additional options
132
+ * @param {boolean} [options.debug] - Enable debug logging
133
+ * @param {boolean} [options.dryRun] - Skip actual API call
134
+ * @param {string} [options.pixel_id] - Override default pixel ID
135
+ * @return {Promise<Object>} CAPI response
136
+ */
76
137
  async track(eventName, props = {}, options = {}) {
77
138
  const body = await this.createEvent(eventName, props, options)
78
139
  return this.sendCAPIRequest(body, options)
79
140
  },
80
141
 
142
+ /**
143
+ * Sends a raw request to Facebook Conversions API
144
+ * @param {Object} body - Request body containing event data
145
+ * @param {Object} [options={}] - Request options
146
+ * @param {boolean} [options.debug] - Log request body
147
+ * @param {boolean} [options.dryRun] - Skip actual API call
148
+ * @param {string} [options.pixel_id] - Override default pixel ID
149
+ * @return {Promise<Object>} CAPI response
150
+ */
81
151
  async sendCAPIRequest(body, options) {
82
152
  const { debug = false, dryRun = false, pixel_id } = options
83
153
  const pixel = pixel_id || pixelID
@@ -97,6 +167,20 @@ export default function FB({ pixelID, testEventCode, accessToken, framework }) {
97
167
  }
98
168
  }
99
169
 
170
+ // ========================
171
+ // Helper Functions
172
+ // ========================
173
+
174
+ /**
175
+ * Gets default event parameters based on the framework and context
176
+ * @param {string} framework - Framework name (astro, express, fastify, koa)
177
+ * @param {Object} context - Framework-specific request context
178
+ * @return {Object} Default event parameters
179
+ * @property {string} event_id - Randomly generated event ID
180
+ * @property {string} action_source - Always set to 'website'
181
+ * @property {number} event_time - Unix timestamp in seconds
182
+ * @property {string} event_source_url - Full URL of the request
183
+ */
100
184
  function getEventParamDefaults(framework, context) {
101
185
  return {
102
186
  event_id: randomString(10),
@@ -106,13 +190,78 @@ function getEventParamDefaults(framework, context) {
106
190
  }
107
191
  }
108
192
 
193
+ /**
194
+ * Extracts the full URL from framework-specific context
195
+ * @param {string} framework - Framework name (astro, express, fastify, koa)
196
+ * @param {Object} context - Framework-specific request context
197
+ * @return {string} Full URL including protocol, host, and path
198
+ */
109
199
  function getUrl(framework, context) {
110
200
  if (framework === 'astro') return context.url.href
201
+ if (framework === 'express') {
202
+ return context.protocol + '://' + context.get('host') + context.originalUrl
203
+ }
204
+ if (framework === 'fastify') {
205
+ return context.protocol + '://' + context.hostname + context.url
206
+ }
207
+ if (framework === 'koa') {
208
+ return context.protocol + '://' + context.host + context.url
209
+ }
111
210
  }
112
211
 
113
- async function normalizeUserData({ context, framework, userProps, fbc, fbp }) {
114
- let ip, userAgent
212
+ /**
213
+ * Extracts client IP address from framework-specific context
214
+ * @param {string} framework - Framework name (astro, express, fastify, koa)
215
+ * @param {Object} context - Framework-specific request context
216
+ * @return {string} Client IP address
217
+ */
218
+ function getIP(framework, context) {
219
+ if (framework === 'astro') return context.clientAddress
220
+ if (framework === 'express')
221
+ return context.ip || context.connection?.remoteAddress
222
+ if (framework === 'fastify') return context.ip
223
+ if (framework === 'koa') return context.ip
224
+ }
225
+
226
+ /**
227
+ * Extracts user agent string from framework-specific context
228
+ * @param {string} framework - Framework name (astro, express, fastify, koa)
229
+ * @param {Object} context - Framework-specific request context
230
+ * @return {string} User agent string
231
+ */
232
+ function getUserAgent(framework, context) {
233
+ if (framework === 'astro') return context.request.headers.get('user-agent')
234
+ if (framework === 'express') return context.get('user-agent')
235
+ if (framework === 'fastify') return context.headers['user-agent']
236
+ if (framework === 'koa') return context.get('user-agent')
237
+ }
115
238
 
239
+ /**
240
+ * Extracts cookie value from framework-specific context
241
+ * @param {string} framework - Framework name (astro, express, fastify, koa)
242
+ * @param {Object} context - Framework-specific request context
243
+ * @param {string} name - Cookie name
244
+ * @return {string} Cookie value
245
+ */
246
+ function getCookie(framework, context, name) {
247
+ if (framework === 'astro') return context.cookies.get(name)?.value
248
+ if (framework === 'express') return context.cookies?.[name]
249
+ if (framework === 'fastify') return context.cookies?.[name]
250
+ if (framework === 'koa') return context.cookies?.get(name)
251
+ }
252
+
253
+ /**
254
+ * Normalizes and enriches user data for Facebook CAPI
255
+ * Hashes required properties and adds client information from request context
256
+ * @param {Object} params - Parameters object
257
+ * @param {Object} params.context - Framework-specific request context
258
+ * @param {string} params.framework - Framework name (astro, express, fastify, koa)
259
+ * @param {Object} params.userProps - User properties to normalize
260
+ * @param {string} [params.fbc] - Facebook click ID cookie
261
+ * @param {string} [params.fbp] - Facebook browser ID cookie
262
+ * @return {Promise<Object>} Normalized user data with hashed properties and client info
263
+ */
264
+ async function normalizeUserData({ context, framework, userProps, fbc, fbp }) {
116
265
  const { p: userPropsToHash, o: otherUserProps } = splitObject(
117
266
  userProps,
118
267
  USER_PROPERTIES_TO_HASH,
@@ -120,13 +269,11 @@ async function normalizeUserData({ context, framework, userProps, fbc, fbp }) {
120
269
 
121
270
  const hashedProps = await formatUserData(userPropsToHash, sha256Hash)
122
271
 
123
- // Get other client data
124
- if (framework === 'astro') {
125
- ip = context.clientAddress
126
- userAgent = context.request.headers.get('user-agent')
127
- if (!fbp) fbp = context.cookies.get('_fbp')?.value
128
- if (!fbc) fbc = context.cookies.get('_fbc')?.value
129
- }
272
+ // Get client data from context
273
+ const ip = getIP(framework, context)
274
+ const userAgent = getUserAgent(framework, context)
275
+ if (!fbp) fbp = getCookie(framework, context, '_fbp')
276
+ if (!fbc) fbc = getCookie(framework, context, '_fbc')
130
277
 
131
278
  const userData = omitEmpty({
132
279
  ...hashedProps,
package/lib/fb/readme.md CHANGED
@@ -1,42 +1,43 @@
1
- Shared config
1
+ Designed to provide a unified interface for Facebook Pixel and Conversion API.
2
+
3
+ ## Setup
4
+
5
+ Config
2
6
 
3
7
  ```js
4
8
  export default {
5
9
  fb: {
6
10
  pixelID: 'PIXEL ID',
7
11
  testEventCode: 'TEST EVENT CODE',
12
+ capiEndpoint: '/api/tracking/facebook/',
13
+ accessToken: import.meta.env.FB_CAPI_TOKEN,
14
+ framework: 'astro', // or 'express', 'fastify', 'koa'
8
15
  },
9
16
  }
10
17
  ```
11
18
 
12
- Setup
19
+ Browser
13
20
 
14
21
  ```js
15
22
  import FB from '@splendidlabz/tracking/fb/web'
16
- import config from './shared'
17
-
18
- export const fb = FB({
19
- ...config.fb,
20
- capiEndpoint: '/api/tracking/facebook/',
21
- })
23
+ import config from './config'
24
+ export const fb = FB(config.fb)
22
25
  ```
23
26
 
24
27
  Server
25
28
 
26
29
  ```js
27
30
  import FB from '@splendidlabz/tracking/fb/node'
28
- import config from './shared'
29
-
30
- export const fb = FB({
31
- ...config.fb,
32
- framework: 'astro',
33
- accessToken: import.meta.env.FB_CAPI_TOKEN,
34
- })
31
+ import config from './config'
32
+ export const fb = FB(config.fb)
35
33
  ```
36
34
 
37
- Ads server for dedupe events
35
+ Include API to dedupe events through CAPI
36
+
37
+ **Astro:**
38
38
 
39
39
  ```js
40
+ // /api/tracking/facebook/
40
41
  import { fb } from '@/services/tracking/node'
41
42
  import { JSONResponse, parseData } from '@splendidlabz/astro/server'
42
43
  export const prerender = false
@@ -49,6 +50,143 @@ export async function POST(context) {
49
50
  }
50
51
  ```
51
52
 
52
- Other stuff necessary.... well... check Facebook docs ba.
53
- Perhaps should include a standard event list , or link to the docs.
54
- Should also notify that `PageView` is going to be tracked as a custom event.
53
+ **Express:**
54
+
55
+ ```js
56
+ // Requires cookie-parser middleware for cookie support
57
+ import express from 'express'
58
+ import cookieParser from 'cookie-parser'
59
+ import { fb } from './services/tracking/node.js'
60
+
61
+ const app = express()
62
+ app.use(express.json())
63
+ app.use(cookieParser())
64
+
65
+ app.post('/api/tracking/facebook', async (req, res) => {
66
+ const { response, error } = await fb.sendEvent(req.body)
67
+ if (response) return res.status(200).json(response.body)
68
+ if (error) return res.status(500).json(error)
69
+ })
70
+ ```
71
+
72
+ **Fastify:**
73
+
74
+ ```js
75
+ // Requires @fastify/cookie plugin for cookie support
76
+ import Fastify from 'fastify'
77
+ import fastifyCookie from '@fastify/cookie'
78
+ import { fb } from './services/tracking/node.js'
79
+
80
+ const fastify = Fastify()
81
+ await fastify.register(fastifyCookie)
82
+
83
+ fastify.post('/api/tracking/facebook', async (request, reply) => {
84
+ const { response, error } = await fb.sendEvent(request.body)
85
+ if (response) return reply.status(200).send(response.body)
86
+ if (error) return reply.status(500).send(error)
87
+ })
88
+ ```
89
+
90
+ **Koa:**
91
+
92
+ ```js
93
+ // Requires koa-bodyparser and koa-cookie middleware
94
+ import Koa from 'koa'
95
+ import bodyParser from 'koa-bodyparser'
96
+ import cookie from 'koa-cookie'
97
+ import { fb } from './services/tracking/node.js'
98
+
99
+ const app = new Koa()
100
+ app.use(bodyParser())
101
+ app.use(cookie())
102
+
103
+ app.use(async (ctx) => {
104
+ if (ctx.path === '/api/tracking/facebook' && ctx.method === 'POST') {
105
+ const { response, error } = await fb.sendEvent(ctx.request.body)
106
+ if (response) {
107
+ ctx.status = 200
108
+ ctx.body = response.body
109
+ }
110
+ if (error) {
111
+ ctx.status = 500
112
+ ctx.body = error
113
+ }
114
+ }
115
+ })
116
+ ```
117
+
118
+ ## Usage
119
+
120
+ Browser:
121
+
122
+ ```js
123
+ fb.track('event_name', { ...props })
124
+ ```
125
+
126
+ Node (requires passing the request context):
127
+
128
+ **Astro:**
129
+
130
+ ```js
131
+ fb.track('event_name', { context, ...props })
132
+ ```
133
+
134
+ **Express:**
135
+
136
+ ```js
137
+ app.post('/some-route', async (req, res) => {
138
+ await fb.track('event_name', { context: req, ...props })
139
+ res.json({ success: true })
140
+ })
141
+ ```
142
+
143
+ **Fastify:**
144
+
145
+ ```js
146
+ fastify.post('/some-route', async (request, reply) => {
147
+ await fb.track('event_name', { context: request, ...props })
148
+ reply.send({ success: true })
149
+ })
150
+ ```
151
+
152
+ **Koa:**
153
+
154
+ ```js
155
+ app.use(async (ctx) => {
156
+ if (ctx.path === '/some-route' && ctx.method === 'POST') {
157
+ await fb.track('event_name', { context: ctx, ...props })
158
+ ctx.body = { success: true }
159
+ }
160
+ })
161
+ ```
162
+
163
+ ## Event Reference
164
+
165
+ - [Standard Event Reference](https://developers.facebook.com/docs/meta-pixel/reference#standard-events)
166
+ - [Advanced Matching Reference](https://developers.facebook.com/docs/meta-pixel/advanced/advanced-matching/)
167
+ - [Conversion API Params Reference](https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters)
168
+
169
+ ## Testing Your Implementation
170
+
171
+ Go to `Events Manager > Datasets > Test Events` and copy your event tracking code. Add it to your config.
172
+
173
+ **IMPORTANT**: Remove `testEventCode` after your tests! You don't want this in your production code.
174
+
175
+ ```js
176
+ export default {
177
+ fb: {
178
+ pixelID: 'PIXEL ID',
179
+ testEventCode: 'TEST EVENT CODE',
180
+ // ...
181
+ },
182
+ }
183
+ ```
184
+
185
+ Under the same `Test Events` tab, enter a website to test with.
186
+
187
+ - Note that localhost cannot be used for browser-testing — FB requires a valid domain
188
+ - To test if server & browser events are deduplicated, use a local tunnel like ngrok.
189
+ - Make sure your website — and your tunnel — is listed under your Pixel's allow list under
190
+ `Dataset > Settings > Allow list`. Feel free to remove the tunnel from the allow list after testing.
191
+
192
+ - Context is to automatically get Client IP Address and User Agent.
package/lib/fb/web.js CHANGED
@@ -1,18 +1,46 @@
1
1
  import { notEmpty, splitObject } from '@splendidlabz/utils'
2
2
  import { getCookie, randomString, sha256Hash } from '@splendidlabz/utils/dom'
3
+ import zlFetch from 'zl-fetch'
3
4
  import {
4
5
  STANDARD_EVENTS,
5
6
  USER_PROPERTIES,
6
7
  USER_PROPERTIES_TO_HASH,
7
8
  } from './consts.js'
8
-
9
- import zlFetch from 'zl-fetch'
10
9
  import { formatUserData } from './utils.js'
11
10
 
11
+ /**
12
+ * Creates a Facebook Pixel and CAPI tracker for client-side tracking
13
+ * @param {Object} config - Configuration options
14
+ * @param {string} config.pixelID - Facebook Pixel ID
15
+ * @param {string} [config.testEventCode] - Test event code for debugging
16
+ * @param {string} config.capiEndpoint - API endpoint for sending CAPI requests
17
+ * @return {Object} FB tracking instance
18
+ * @property {Function} init - Initialize Facebook Pixel
19
+ * @property {Function} createEvent - Create event data for both Pixel and CAPI
20
+ * @property {Function} track - Track event via both Pixel and CAPI
21
+ * @property {Function} sendPixelEvent - Send event to Facebook Pixel
22
+ * @property {Function} sendCAPIRequest - Send event to CAPI endpoint
23
+ */
12
24
  export default function FB({ pixelID, testEventCode, capiEndpoint }) {
13
25
  return {
26
+ /**
27
+ * Initializes the Facebook Pixel on the page
28
+ * @return {void}
29
+ */
14
30
  init: _ => initPixel(pixelID),
15
31
 
32
+ /**
33
+ * Creates event data for both Facebook Pixel and CAPI
34
+ * @param {string} event_name - Name of the event to track
35
+ * @param {Object} [props={}] - Event properties and user data
36
+ * @param {string} [props.eventURL] - Custom URL for the event (defaults to current page)
37
+ * @param {string} [props.actionSource] - Action source (defaults to 'website')
38
+ * @param {Object} [options={}] - Additional options
39
+ * @param {boolean} [options.debug] - Enable debug logging
40
+ * @return {Promise<Object>} Object containing pixelData and capiData
41
+ * @property {Object} pixelData - Data formatted for Facebook Pixel
42
+ * @property {Object} capiData - Data formatted for CAPI
43
+ */
16
44
  async createEvent(event_name, props = {}, options = {}) {
17
45
  const { debug = false } = options
18
46
  const { eventURL, actionSource, ...r } = props
@@ -61,6 +89,15 @@ export default function FB({ pixelID, testEventCode, capiEndpoint }) {
61
89
  return { pixelData, capiData }
62
90
  },
63
91
 
92
+ /**
93
+ * Tracks an event by sending to both Facebook Pixel and CAPI
94
+ * @param {string} event_name - Name of the event to track
95
+ * @param {Object} [props={}] - Event properties and user data
96
+ * @param {Object} [options={}] - Additional options
97
+ * @param {boolean} [options.debug] - Enable debug logging
98
+ * @param {boolean} [options.dryRun] - Skip actual tracking (for testing)
99
+ * @return {Promise<Object>} CAPI response body
100
+ */
64
101
  async track(event_name, props = {}, options = {}) {
65
102
  const { debug = false, dryRun = false } = options
66
103
  const { pixelData, capiData } = await this.createEvent(
@@ -78,11 +115,20 @@ export default function FB({ pixelID, testEventCode, capiEndpoint }) {
78
115
  return response.body
79
116
  },
80
117
 
81
- // Facebook Pixel Code
82
- // Pixel Standard Reference
83
- // https://developers.facebook.com/docs/meta-pixel/reference#standard-events
84
- // For Advanced Matching when user data is available
85
- // https://developers.facebook.com/docs/meta-pixel/advanced/advanced-matching/
118
+ /**
119
+ * Sends an event to Facebook Pixel
120
+ * Supports standard events, custom events, and advanced matching
121
+ * @param {Object} data - Event data
122
+ * @param {string} data.pixelID - Pixel ID
123
+ * @param {string} data.eventID - Event ID for deduplication
124
+ * @param {string} data.event_name - Event name (use 'init' to initialize pixel)
125
+ * @param {Object} [data.user_data] - User data for advanced matching
126
+ * @param {Object} [options] - Options
127
+ * @param {boolean} [options.debug] - Enable debug logging
128
+ * @return {void}
129
+ * @see https://developers.facebook.com/docs/meta-pixel/reference#standard-events
130
+ * @see https://developers.facebook.com/docs/meta-pixel/advanced/advanced-matching/
131
+ */
86
132
  sendPixelEvent(data, { debug = false }) {
87
133
  const { pixelID, eventID, event_name, user_data = {}, ...rest } = data
88
134
  const hasUserData = notEmpty(user_data)
@@ -109,13 +155,24 @@ export default function FB({ pixelID, testEventCode, capiEndpoint }) {
109
155
  }
110
156
  },
111
157
 
112
- // CAPI Parameters: https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters
158
+ /**
159
+ * Sends a request to the CAPI endpoint
160
+ * @param {Object} data - CAPI event data
161
+ * @return {Promise<Object>} Response from CAPI endpoint
162
+ * @see https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters
163
+ */
113
164
  sendCAPIRequest(data) {
114
165
  return zlFetch.post(capiEndpoint, { body: data })
115
166
  },
116
167
  }
117
168
  }
118
169
 
170
+ /**
171
+ * Initializes the Facebook Pixel by loading the fbevents.js script
172
+ * @param {string} pixelID - Facebook Pixel ID
173
+ * @return {void}
174
+ * @throws {Error} If called outside of browser environment
175
+ */
119
176
  function initPixel(pixelID) {
120
177
  // eslint-disable-next-line
121
178
  !(function (f, b, e, v, n, t, s) {
@@ -72,7 +72,7 @@ export default function (config = {}) {
72
72
  * @param {string} [properties.userId] - User ID (used for distinct ID)
73
73
  * @param {Object} [properties.context] - Request context (for cookie access)
74
74
  * @param {...*} properties.rest - Additional event properties
75
- * @return {Promise|undefined} PostHog capture promise, or undefined if trackDevEvents is true
75
+ * @return {Promise|undefined} PostHog capture promise, or undefined if trackEvents is false
76
76
  */
77
77
  capture(event, properties = {}) {
78
78
  if (!trackEvents) return
@@ -88,7 +88,7 @@ export default function (config = {}) {
88
88
  * Sets person properties on the current user
89
89
  * @param {Object} [set={}] - Properties to set (will overwrite existing values)
90
90
  * @param {Object} [once={}] - Properties to set only once (won't overwrite existing values)
91
- * @return {Promise|undefined} PostHog capture promise, or undefined if trackDevEvents is true
91
+ * @return {Promise|undefined} PostHog capture promise, or undefined if trackEvents is false
92
92
  */
93
93
  setPersonProperties(set = {}, once = {}) {
94
94
  if (!trackEvents) return
@@ -104,7 +104,7 @@ export default function (config = {}) {
104
104
  /**
105
105
  * Removes person properties from the current user
106
106
  * @param {string[]} properties - List of property names to remove
107
- * @return {Promise|undefined} PostHog capture promise, or undefined if trackDevEvents is true
107
+ * @return {Promise|undefined} PostHog capture promise, or undefined if trackEvents is false
108
108
  */
109
109
  removePersonProperties(properties) {
110
110
  if (!trackEvents) return
@@ -15,3 +15,11 @@ This package assumes you're using Posthog for both web and node.js.
15
15
 
16
16
  - Get distinct_id from cookies on the backend automatically when using Astro — just provide context.
17
17
  - Use `trackEvents:false` to disable tracking completely when developing.
18
+
19
+ ## Filtering out local development environments
20
+
21
+ You can create filters which include more than one value by separating values with a comma. We use such a filter to exclude events from local development environments, for example:
22
+
23
+ Host ≠ (doesn’t equal) localhost:8000,localhost:5000,127.0.0.1:8000
24
+
25
+ You can also create filters based on pre-prepared cohorts of users, which is especially useful if you’re using cohorts with Feature Flags or to run Experiments. To do this, simply select the cohort you wish to add to your internal and test user list.
@@ -41,7 +41,8 @@ export default function (config = {}) {
41
41
 
42
42
  /**
43
43
  * Set properties for the current person
44
- * @param {...any} props - Properties to set for the person
44
+ * @param {object} [set={}] - Properties to set (will overwrite existing values)
45
+ * @param {object} [once={}] - Properties to set only once (won't overwrite existing values)
45
46
  * @returns {void}
46
47
  */
47
48
  setPersonProperties(set = {}, once = {}) {
@@ -50,8 +51,9 @@ export default function (config = {}) {
50
51
  },
51
52
 
52
53
  /**
54
+ * Identify a user with PostHog. If the distinctId differs from the existing cookie ID, creates a new identity; otherwise updates properties.
53
55
  * @param {string} distinctId - New unique identifier for the user (email, userId, etc.)
54
- * @param {object} properties - The properties to set for the user
56
+ * @param {object} [properties={}] - The properties to set for the user
55
57
  * @returns {void}
56
58
  */
57
59
  identify(distinctId, properties = {}) {
@@ -67,6 +69,7 @@ export default function (config = {}) {
67
69
  },
68
70
 
69
71
  /**
72
+ * Create an alias for a user, linking two distinct IDs together
70
73
  * @param {string} distinctId - New unique identifier for the user
71
74
  * @param {string} aliasId - Alias for the user
72
75
  * @returns {void}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splendidlabz/tracking",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Simple Tracking Helper",
5
5
  "type": "module",
6
6
  "files": [