@codaco/analytics 9.0.0 → 11.0.0
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/CHANGELOG.md +30 -0
- package/LICENSE +674 -0
- package/README.md +174 -305
- package/dist/{chunk-3NEQVIC4.js → chunk-TPZBZWEN.js} +19 -18
- package/dist/chunk-TPZBZWEN.js.map +1 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.js +20 -9
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/dist/{types-Ymgjicqi.d.ts → types-BxfgCtu7.d.ts} +20 -8
- package/package.json +8 -8
- package/src/__tests__/client.test.ts +3 -1
- package/src/__tests__/index.test.ts +37 -1
- package/src/client.ts +2 -1
- package/src/config.ts +1 -0
- package/src/index.ts +5 -2
- package/src/provider.tsx +2 -2
- package/src/server.ts +1 -0
- package/src/types.ts +31 -7
- package/tsconfig.json +1 -1
- package/dist/chunk-3NEQVIC4.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# @codaco/analytics
|
|
2
2
|
|
|
3
|
-
PostHog analytics wrapper for Network Canvas applications with installation ID tracking, error reporting, and feature flags
|
|
3
|
+
PostHog analytics wrapper for Network Canvas applications with multi-app support, installation ID tracking, error reporting, and feature flags.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This package provides a simplified abstraction over PostHog analytics, designed
|
|
7
|
+
This package provides a simplified abstraction over PostHog analytics, designed for Network Canvas applications. Multiple apps (Fresco, Architect, Studio, etc.) share a single PostHog project, with events segmented by the required `app` property. Every event also includes an `installationId`, making it possible to track deployments without compromising user privacy.
|
|
8
8
|
|
|
9
9
|
**Important:** This package is designed to work exclusively with the Cloudflare Worker reverse proxy at `ph-relay.networkcanvas.com`. All PostHog authentication is handled by the worker, so you don't need to configure API keys in your application.
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
|
+
- **Multi-App Support**: Segment events by application within a single PostHog project
|
|
13
14
|
- **Installation ID Tracking**: Automatically includes installation ID with every event
|
|
14
15
|
- **Error Tracking**: Capture errors with full stack traces
|
|
15
16
|
- **Feature Flags**: Built-in support for PostHog feature flags and A/B testing
|
|
@@ -37,86 +38,152 @@ DISABLE_ANALYTICS=true
|
|
|
37
38
|
NEXT_PUBLIC_DISABLE_ANALYTICS=true
|
|
38
39
|
```
|
|
39
40
|
|
|
40
|
-
### Client-Side Usage
|
|
41
|
+
### Client-Side Usage
|
|
42
|
+
|
|
43
|
+
#### Pattern A: `instrumentation-client.ts` (recommended for Next.js 16+)
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// instrumentation-client.ts
|
|
47
|
+
import { createAnalytics, mergeConfig } from "@codaco/analytics";
|
|
48
|
+
|
|
49
|
+
createAnalytics(
|
|
50
|
+
mergeConfig({
|
|
51
|
+
app: "Fresco",
|
|
52
|
+
installationId: process.env.NEXT_PUBLIC_INSTALLATION_ID!,
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Pattern B: React Provider (still supported)
|
|
41
58
|
|
|
42
59
|
```tsx
|
|
43
|
-
//
|
|
44
|
-
import { AnalyticsProvider } from
|
|
60
|
+
// app/layout.tsx
|
|
61
|
+
import { AnalyticsProvider } from "@codaco/analytics";
|
|
45
62
|
|
|
46
63
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
return (
|
|
65
|
+
<html>
|
|
66
|
+
<body>
|
|
67
|
+
<AnalyticsProvider
|
|
68
|
+
config={{
|
|
69
|
+
app: "Fresco",
|
|
70
|
+
installationId: "your-unique-installation-id",
|
|
71
|
+
}}
|
|
72
|
+
>
|
|
73
|
+
{children}
|
|
74
|
+
</AnalyticsProvider>
|
|
75
|
+
</body>
|
|
76
|
+
</html>
|
|
77
|
+
);
|
|
60
78
|
}
|
|
61
79
|
```
|
|
62
80
|
|
|
63
81
|
```tsx
|
|
64
82
|
// In your components
|
|
65
|
-
import { useAnalytics } from
|
|
83
|
+
import { useAnalytics } from "@codaco/analytics";
|
|
66
84
|
|
|
67
85
|
export function MyComponent() {
|
|
68
|
-
|
|
86
|
+
const { trackEvent, trackError } = useAnalytics();
|
|
69
87
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
88
|
+
const handleSetup = () => {
|
|
89
|
+
trackEvent("app_setup", {
|
|
90
|
+
metadata: { version: "1.0.0" },
|
|
91
|
+
});
|
|
92
|
+
};
|
|
75
93
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
94
|
+
const handleError = (error: Error) => {
|
|
95
|
+
trackError(error, {
|
|
96
|
+
metadata: { context: "component-mount" },
|
|
97
|
+
});
|
|
98
|
+
};
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
return <button onClick={handleSetup}>Setup App</button>;
|
|
83
101
|
}
|
|
84
102
|
```
|
|
85
103
|
|
|
86
104
|
### Server-Side Usage
|
|
87
105
|
|
|
106
|
+
#### `instrumentation.ts` (recommended for Next.js 16+)
|
|
107
|
+
|
|
88
108
|
```ts
|
|
89
|
-
//
|
|
90
|
-
|
|
109
|
+
// instrumentation.ts
|
|
110
|
+
export async function register() {
|
|
111
|
+
if (process.env.NEXT_RUNTIME === "nodejs") {
|
|
112
|
+
const { initServerAnalytics } = await import("@codaco/analytics/server");
|
|
113
|
+
initServerAnalytics({
|
|
114
|
+
app: "Fresco",
|
|
115
|
+
installationId: process.env.INSTALLATION_ID!,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Direct initialization
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { initServerAnalytics } from "@codaco/analytics/server";
|
|
91
125
|
|
|
92
126
|
initServerAnalytics({
|
|
93
|
-
|
|
127
|
+
app: "Fresco",
|
|
128
|
+
installationId: "your-unique-installation-id",
|
|
94
129
|
});
|
|
95
130
|
|
|
96
131
|
// Then use in API routes or server actions
|
|
97
|
-
import { serverAnalytics } from
|
|
132
|
+
import { serverAnalytics } from "@codaco/analytics/server";
|
|
98
133
|
|
|
99
134
|
export async function POST(request: Request) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return Response.json({ error: 'Failed' }, { status: 500 });
|
|
111
|
-
}
|
|
135
|
+
try {
|
|
136
|
+
serverAnalytics.trackEvent("data_exported", {
|
|
137
|
+
metadata: { format: "csv", rowCount: 100 },
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return Response.json({ success: true });
|
|
141
|
+
} catch (error) {
|
|
142
|
+
serverAnalytics.trackError(error as Error);
|
|
143
|
+
return Response.json({ error: "Failed" }, { status: 500 });
|
|
144
|
+
}
|
|
112
145
|
}
|
|
113
146
|
```
|
|
114
147
|
|
|
115
148
|
## API Reference
|
|
116
149
|
|
|
150
|
+
### Config Options
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
interface AnalyticsConfig {
|
|
154
|
+
// Required: Application identifier for PostHog segmentation
|
|
155
|
+
app: "Fresco" | "Studio" | "Architect" | "Interviewer" | "ArchitectWeb" | "CommunityForum" | "ProjectWebsite" | "Documentation";
|
|
156
|
+
|
|
157
|
+
// Required: Unique identifier for this installation
|
|
158
|
+
installationId: string;
|
|
159
|
+
|
|
160
|
+
// Optional: PostHog API key
|
|
161
|
+
// Defaults to a placeholder (authentication handled by the proxy)
|
|
162
|
+
apiKey?: string;
|
|
163
|
+
|
|
164
|
+
// Optional: PostHog API host
|
|
165
|
+
// Hardcoded to "https://ph-relay.networkcanvas.com" by default
|
|
166
|
+
apiHost?: string;
|
|
167
|
+
|
|
168
|
+
// Optional: Disable all tracking
|
|
169
|
+
disabled?: boolean;
|
|
170
|
+
|
|
171
|
+
// Optional: Enable debug mode
|
|
172
|
+
debug?: boolean;
|
|
173
|
+
|
|
174
|
+
// Optional: PostHog-specific options
|
|
175
|
+
posthogOptions?: {
|
|
176
|
+
disable_session_recording?: boolean;
|
|
177
|
+
autocapture?: boolean;
|
|
178
|
+
capture_pageview?: boolean;
|
|
179
|
+
// ... other PostHog options
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
117
184
|
### Event Types
|
|
118
185
|
|
|
119
|
-
The package
|
|
186
|
+
The package includes common event types for discoverability:
|
|
120
187
|
|
|
121
188
|
- `app_setup` - Initial application setup
|
|
122
189
|
- `protocol_installed` - Protocol installation
|
|
@@ -125,7 +192,7 @@ The package supports the following standard event types:
|
|
|
125
192
|
- `data_exported` - Data export
|
|
126
193
|
- `error` - Error events (use `trackError()` instead)
|
|
127
194
|
|
|
128
|
-
|
|
195
|
+
This list is non-exhaustive. `trackEvent` accepts any string as the event name.
|
|
129
196
|
|
|
130
197
|
### Client-Side API
|
|
131
198
|
|
|
@@ -134,41 +201,16 @@ You can also send custom events with any string name.
|
|
|
134
201
|
Wraps your application to provide analytics context.
|
|
135
202
|
|
|
136
203
|
```tsx
|
|
137
|
-
<AnalyticsProvider config={config}>
|
|
138
|
-
{children}
|
|
139
|
-
</AnalyticsProvider>
|
|
204
|
+
<AnalyticsProvider config={config}>{children}</AnalyticsProvider>
|
|
140
205
|
```
|
|
141
206
|
|
|
142
|
-
|
|
207
|
+
#### `createAnalytics(config)`
|
|
143
208
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// Optional: PostHog API key
|
|
150
|
-
// Defaults to a placeholder (authentication handled by the proxy)
|
|
151
|
-
apiKey?: string;
|
|
152
|
-
|
|
153
|
-
// Optional: PostHog API host
|
|
154
|
-
// Hardcoded to "https://ph-relay.networkcanvas.com" by default
|
|
155
|
-
// Only override if using a different proxy endpoint
|
|
156
|
-
apiHost?: string;
|
|
157
|
-
|
|
158
|
-
// Optional: Disable all tracking
|
|
159
|
-
disabled?: boolean;
|
|
160
|
-
|
|
161
|
-
// Optional: Enable debug mode
|
|
162
|
-
debug?: boolean;
|
|
163
|
-
|
|
164
|
-
// Optional: PostHog-specific options
|
|
165
|
-
posthogOptions?: {
|
|
166
|
-
disable_session_recording?: boolean;
|
|
167
|
-
autocapture?: boolean;
|
|
168
|
-
capture_pageview?: boolean;
|
|
169
|
-
// ... other PostHog options
|
|
170
|
-
};
|
|
171
|
-
}
|
|
209
|
+
Creates a client-side analytics instance directly. Useful for `instrumentation-client.ts`.
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import { createAnalytics, mergeConfig } from "@codaco/analytics";
|
|
213
|
+
const analytics = createAnalytics(mergeConfig({ app: "Fresco", installationId: "..." }));
|
|
172
214
|
```
|
|
173
215
|
|
|
174
216
|
#### `useAnalytics()`
|
|
@@ -177,106 +219,49 @@ React hook to access analytics in components.
|
|
|
177
219
|
|
|
178
220
|
```tsx
|
|
179
221
|
const analytics = useAnalytics();
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
analytics.
|
|
183
|
-
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Track an error
|
|
187
|
-
analytics.trackError(error, {
|
|
188
|
-
metadata: { context: 'import' }
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
// Feature flags
|
|
192
|
-
const isEnabled = analytics.isFeatureEnabled('new-feature');
|
|
193
|
-
const variant = analytics.getFeatureFlag('experiment');
|
|
194
|
-
const allFlags = analytics.getFeatureFlags();
|
|
222
|
+
analytics.trackEvent("protocol_installed", { metadata: { protocolId: "123" } });
|
|
223
|
+
analytics.trackError(error, { metadata: { context: "import" } });
|
|
224
|
+
analytics.isFeatureEnabled("new-feature");
|
|
225
|
+
analytics.getFeatureFlag("experiment");
|
|
195
226
|
analytics.reloadFeatureFlags();
|
|
196
|
-
|
|
197
|
-
// User identification (optional, for advanced use cases)
|
|
198
|
-
analytics.identify('user-123', { email: 'user@example.com' });
|
|
227
|
+
analytics.identify("user-123", { email: "user@example.com" });
|
|
199
228
|
analytics.reset();
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
analytics.isEnabled(); // Check if analytics is enabled
|
|
203
|
-
analytics.getInstallationId(); // Get the installation ID
|
|
229
|
+
analytics.isEnabled();
|
|
230
|
+
analytics.getInstallationId();
|
|
204
231
|
```
|
|
205
232
|
|
|
206
233
|
#### `useFeatureFlag(flagKey: string)`
|
|
207
234
|
|
|
208
235
|
React hook for feature flags (returns boolean).
|
|
209
236
|
|
|
210
|
-
```tsx
|
|
211
|
-
const isNewUIEnabled = useFeatureFlag('new-ui');
|
|
212
|
-
|
|
213
|
-
if (isNewUIEnabled) {
|
|
214
|
-
return <NewUI />;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return <OldUI />;
|
|
218
|
-
```
|
|
219
|
-
|
|
220
237
|
#### `useFeatureFlagValue(flagKey: string)`
|
|
221
238
|
|
|
222
239
|
React hook for multivariate feature flags.
|
|
223
240
|
|
|
224
|
-
```tsx
|
|
225
|
-
const theme = useFeatureFlagValue('theme-experiment');
|
|
226
|
-
|
|
227
|
-
return <div className={theme === 'dark' ? 'dark' : 'light'}>
|
|
228
|
-
Content
|
|
229
|
-
</div>;
|
|
230
|
-
```
|
|
231
|
-
|
|
232
241
|
### Server-Side API
|
|
233
242
|
|
|
234
243
|
#### `serverAnalytics`
|
|
235
244
|
|
|
236
|
-
Pre-configured server-side analytics instance (
|
|
237
|
-
|
|
238
|
-
```ts
|
|
239
|
-
import { serverAnalytics } from '@codaco/analytics/server';
|
|
240
|
-
|
|
241
|
-
serverAnalytics.trackEvent('interview_completed', {
|
|
242
|
-
metadata: { duration: 300, completionRate: 0.95 }
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
serverAnalytics.trackError(error);
|
|
246
|
-
```
|
|
245
|
+
Pre-configured server-side analytics instance (requires `initServerAnalytics()` first).
|
|
247
246
|
|
|
248
247
|
#### `initServerAnalytics(config)`
|
|
249
248
|
|
|
250
|
-
Initialize server analytics
|
|
251
|
-
|
|
252
|
-
```ts
|
|
253
|
-
import { initServerAnalytics, getServerAnalytics } from '@codaco/analytics/server';
|
|
249
|
+
Initialize server analytics. Call once in your app startup.
|
|
254
250
|
|
|
255
|
-
|
|
256
|
-
initServerAnalytics({
|
|
257
|
-
installationId: 'your-unique-installation-id',
|
|
258
|
-
// Optional overrides:
|
|
259
|
-
// disabled: false,
|
|
260
|
-
// debug: true,
|
|
261
|
-
});
|
|
251
|
+
#### `getServerAnalytics()`
|
|
262
252
|
|
|
263
|
-
|
|
264
|
-
const analytics = getServerAnalytics();
|
|
265
|
-
analytics.trackEvent('app_setup');
|
|
266
|
-
```
|
|
253
|
+
Get the server-side analytics instance.
|
|
267
254
|
|
|
268
|
-
**Note:** Feature flags are **not supported** in server-side mode.
|
|
255
|
+
**Note:** Feature flags are **not supported** in server-side mode.
|
|
269
256
|
|
|
270
257
|
## Configuration
|
|
271
258
|
|
|
272
259
|
### Default Settings
|
|
273
260
|
|
|
274
|
-
The package comes with sensible defaults (no environment variables needed):
|
|
275
|
-
|
|
276
261
|
```typescript
|
|
277
262
|
{
|
|
278
|
-
apiHost: "https://ph-relay.networkcanvas.com",
|
|
279
|
-
apiKey: "phc_proxy_mode_placeholder",
|
|
263
|
+
apiHost: "https://ph-relay.networkcanvas.com",
|
|
264
|
+
apiKey: "phc_proxy_mode_placeholder",
|
|
280
265
|
disabled: false,
|
|
281
266
|
debug: false,
|
|
282
267
|
posthogOptions: {
|
|
@@ -291,172 +276,57 @@ The package comes with sensible defaults (no environment variables needed):
|
|
|
291
276
|
}
|
|
292
277
|
```
|
|
293
278
|
|
|
294
|
-
### Configuration
|
|
295
|
-
|
|
296
|
-
All configuration is passed directly via the `config` prop.
|
|
297
|
-
|
|
298
|
-
**Environment Variables:**
|
|
299
|
-
- `DISABLE_ANALYTICS` or `NEXT_PUBLIC_DISABLE_ANALYTICS` - Set to `"true"` to disable all tracking
|
|
300
|
-
|
|
301
|
-
No other environment variables are used (API host and key are hardcoded for proxy mode).
|
|
302
|
-
|
|
303
279
|
### Disabling Analytics
|
|
304
280
|
|
|
305
|
-
Analytics can be disabled
|
|
281
|
+
Analytics can be disabled via environment variable or config:
|
|
306
282
|
|
|
307
|
-
**1. Via environment variable (recommended for development/testing):**
|
|
308
283
|
```bash
|
|
309
284
|
DISABLE_ANALYTICS=true
|
|
310
|
-
# or
|
|
285
|
+
# or
|
|
311
286
|
NEXT_PUBLIC_DISABLE_ANALYTICS=true
|
|
312
287
|
```
|
|
313
288
|
|
|
314
|
-
**2. Via config prop:**
|
|
315
289
|
```tsx
|
|
316
|
-
<AnalyticsProvider config={{
|
|
317
|
-
|
|
318
|
-
disabled: true
|
|
319
|
-
}}>
|
|
320
|
-
{children}
|
|
290
|
+
<AnalyticsProvider config={{ app: "Fresco", installationId: "...", disabled: true }}>
|
|
291
|
+
{children}
|
|
321
292
|
</AnalyticsProvider>
|
|
322
293
|
```
|
|
323
294
|
|
|
324
|
-
When disabled (by either method), all analytics methods become no-ops (no tracking occurs).
|
|
325
|
-
|
|
326
|
-
## Feature Flags & A/B Testing
|
|
327
|
-
|
|
328
|
-
PostHog feature flags allow you to:
|
|
329
|
-
|
|
330
|
-
- Toggle features on/off remotely
|
|
331
|
-
- Run A/B tests
|
|
332
|
-
- Gradual rollouts
|
|
333
|
-
- User targeting
|
|
334
|
-
|
|
335
|
-
### Setting Up Feature Flags
|
|
336
|
-
|
|
337
|
-
1. Create a feature flag in your PostHog dashboard
|
|
338
|
-
2. Use the hooks or API in your code:
|
|
339
|
-
|
|
340
|
-
```tsx
|
|
341
|
-
function ExperimentComponent() {
|
|
342
|
-
const variant = useFeatureFlagValue('checkout-flow');
|
|
343
|
-
|
|
344
|
-
switch (variant) {
|
|
345
|
-
case 'variant-a':
|
|
346
|
-
return <CheckoutFlowA />;
|
|
347
|
-
case 'variant-b':
|
|
348
|
-
return <CheckoutFlowB />;
|
|
349
|
-
default:
|
|
350
|
-
return <CheckoutFlowDefault />;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
## Error Tracking
|
|
356
|
-
|
|
357
|
-
Errors are automatically enriched with:
|
|
358
|
-
|
|
359
|
-
- Error message
|
|
360
|
-
- Error name
|
|
361
|
-
- Full stack trace
|
|
362
|
-
- Cause (if available)
|
|
363
|
-
- Any additional metadata you provide
|
|
364
|
-
|
|
365
|
-
```tsx
|
|
366
|
-
try {
|
|
367
|
-
// Your code
|
|
368
|
-
} catch (error) {
|
|
369
|
-
trackError(error as Error, {
|
|
370
|
-
metadata: {
|
|
371
|
-
context: 'data-import',
|
|
372
|
-
fileName: 'protocol.json',
|
|
373
|
-
attemptNumber: 3,
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
## Migration from Old Analytics
|
|
380
|
-
|
|
381
|
-
See [MIGRATION.md](./MIGRATION.md) for a complete migration guide from the old analytics system.
|
|
382
|
-
|
|
383
|
-
Quick summary of changes:
|
|
384
|
-
|
|
385
|
-
- **Event names**: Now use `snake_case` instead of `PascalCase`
|
|
386
|
-
- `AppSetup` → `app_setup`
|
|
387
|
-
- `ProtocolInstalled` → `protocol_installed`
|
|
388
|
-
- **API**: `makeEventTracker()` → `useAnalytics()` hook
|
|
389
|
-
- **Route handler**: No longer needed (PostHog handles everything)
|
|
390
|
-
- **Installation ID**: Now set via config instead of route handler
|
|
391
|
-
|
|
392
295
|
## Architecture
|
|
393
296
|
|
|
394
|
-
This package uses a reverse proxy architecture for security and reliability:
|
|
395
|
-
|
|
396
297
|
```
|
|
397
|
-
┌─────────────────────┐
|
|
398
|
-
│
|
|
399
|
-
│
|
|
400
|
-
|
|
401
|
-
│
|
|
402
|
-
|
|
403
|
-
│
|
|
404
|
-
│
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
│
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
│
|
|
411
|
-
│
|
|
412
|
-
│
|
|
413
|
-
|
|
414
|
-
│
|
|
415
|
-
│
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
│
|
|
420
|
-
│
|
|
421
|
-
|
|
422
|
-
┌─────────────────────┐
|
|
423
|
-
│ PostHog Cloud │
|
|
424
|
-
│ (US Region) │
|
|
425
|
-
│ │
|
|
426
|
-
│ Analytics Dashboard│
|
|
427
|
-
│ Feature Flags │
|
|
428
|
-
│ A/B Testing │
|
|
429
|
-
└─────────────────────┘
|
|
298
|
+
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
|
|
299
|
+
│ Fresco │ │ Architect-Web │ │ Studio │
|
|
300
|
+
│ app: "Fresco" │ │ app: "ArchitectWeb" │ │ app: "Studio" │
|
|
301
|
+
└──────────┬──────────┘ └──────────┬──────────┘ └──────────┬──────────┘
|
|
302
|
+
│ │ │
|
|
303
|
+
└────────────┬───────────┘────────────────────────┘
|
|
304
|
+
│
|
|
305
|
+
│ HTTPS (app super property on every event)
|
|
306
|
+
↓
|
|
307
|
+
┌─────────────────────┐
|
|
308
|
+
│ Cloudflare Worker │
|
|
309
|
+
│ ph-relay.network │
|
|
310
|
+
│ canvas.com │
|
|
311
|
+
│ • Injects API key │
|
|
312
|
+
│ • Adds CORS │
|
|
313
|
+
│ • Bypasses blockers│
|
|
314
|
+
└──────────┬──────────┘
|
|
315
|
+
│
|
|
316
|
+
│ HTTPS + Auth
|
|
317
|
+
↓
|
|
318
|
+
┌─────────────────────┐
|
|
319
|
+
│ PostHog Cloud │
|
|
320
|
+
│ (Single Project) │
|
|
321
|
+
│ Filter by app prop │
|
|
322
|
+
└─────────────────────┘
|
|
430
323
|
```
|
|
431
324
|
|
|
432
|
-
|
|
433
|
-
- API key stays secure (server-side only)
|
|
434
|
-
- Avoids ad-blockers
|
|
435
|
-
- Uses your own domain
|
|
436
|
-
- Centralized authentication
|
|
437
|
-
|
|
438
|
-
## Best Practices
|
|
439
|
-
|
|
440
|
-
1. **Always include metadata**: Helps with debugging and analysis
|
|
441
|
-
```ts
|
|
442
|
-
trackEvent('data_exported', {
|
|
443
|
-
metadata: { format: 'csv', size: 1024, duration: 230 }
|
|
444
|
-
});
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
2. **Use typed event names**: Import event types for autocomplete
|
|
448
|
-
```ts
|
|
449
|
-
import type { EventType } from '@codaco/analytics';
|
|
450
|
-
const event: EventType = 'app_setup';
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
3. **Don't block on analytics**: All calls are non-blocking by design
|
|
454
|
-
|
|
455
|
-
4. **Test with analytics disabled**: Set `NEXT_PUBLIC_DISABLE_ANALYTICS=true`
|
|
325
|
+
## Troubleshooting
|
|
456
326
|
|
|
457
|
-
|
|
327
|
+
### `posthog-js` bundling issues with Turbopack
|
|
458
328
|
|
|
459
|
-
|
|
329
|
+
Certain `posthog-js` versions have Turbopack bundling issues when used in `instrumentation-client.ts`. If you encounter `node:child_process` errors, either pin to a compatible `posthog-js` version or fall back to the React Provider pattern.
|
|
460
330
|
|
|
461
331
|
### Events not appearing in PostHog
|
|
462
332
|
|
|
@@ -464,8 +334,6 @@ This package uses a reverse proxy architecture for security and reliability:
|
|
|
464
334
|
2. Check that the Cloudflare Worker has the `POSTHOG_API_KEY` environment variable set
|
|
465
335
|
3. Enable debug mode: `debug: true` in config
|
|
466
336
|
4. Check browser console for errors
|
|
467
|
-
5. Verify PostHog dashboard shows your project
|
|
468
|
-
6. Test the proxy endpoint directly: `curl https://ph-relay.networkcanvas.com`
|
|
469
337
|
|
|
470
338
|
### Feature flags not working
|
|
471
339
|
|
|
@@ -474,11 +342,12 @@ This package uses a reverse proxy architecture for security and reliability:
|
|
|
474
342
|
3. Reload flags: `analytics.reloadFeatureFlags()`
|
|
475
343
|
4. Feature flags only work client-side, not in server components
|
|
476
344
|
|
|
477
|
-
|
|
345
|
+
## Migration from v9
|
|
478
346
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
347
|
+
- `app` is a new **required** field on `AnalyticsConfig`. All consuming apps must pass it.
|
|
348
|
+
- `createAnalytics` is now a public export for use in `instrumentation-client.ts`.
|
|
349
|
+
- `AppName` and `appNames` are new exports.
|
|
350
|
+
- Event types are documented as non-exhaustive.
|
|
482
351
|
|
|
483
352
|
## License
|
|
484
353
|
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
// src/utils.ts
|
|
2
|
+
function ensureError(value) {
|
|
3
|
+
if (!value) return new Error("No value was thrown");
|
|
4
|
+
if (value instanceof Error) return value;
|
|
5
|
+
if (Object.prototype.isPrototypeOf.call(value, Error)) return value;
|
|
6
|
+
let stringified = "[Unable to stringify the thrown value]";
|
|
7
|
+
try {
|
|
8
|
+
stringified = JSON.stringify(value);
|
|
9
|
+
} catch (e) {
|
|
10
|
+
console.error(e);
|
|
11
|
+
}
|
|
12
|
+
const error = new Error(`This value was thrown as is, not through an Error: ${stringified}`);
|
|
13
|
+
return error;
|
|
14
|
+
}
|
|
15
|
+
|
|
1
16
|
// src/config.ts
|
|
2
17
|
var POSTHOG_PROXY_HOST = "https://ph-relay.networkcanvas.com";
|
|
3
18
|
var PROXY_MODE_DUMMY_KEY = "phc_proxy_mode_placeholder";
|
|
@@ -36,6 +51,7 @@ var defaultConfig = {
|
|
|
36
51
|
};
|
|
37
52
|
function mergeConfig(userConfig) {
|
|
38
53
|
return {
|
|
54
|
+
app: userConfig.app,
|
|
39
55
|
apiHost: userConfig.apiHost ?? defaultConfig.apiHost ?? POSTHOG_PROXY_HOST,
|
|
40
56
|
apiKey: userConfig.apiKey ?? PROXY_MODE_DUMMY_KEY,
|
|
41
57
|
installationId: userConfig.installationId,
|
|
@@ -48,25 +64,10 @@ function mergeConfig(userConfig) {
|
|
|
48
64
|
};
|
|
49
65
|
}
|
|
50
66
|
|
|
51
|
-
// src/utils.ts
|
|
52
|
-
function ensureError(value) {
|
|
53
|
-
if (!value) return new Error("No value was thrown");
|
|
54
|
-
if (value instanceof Error) return value;
|
|
55
|
-
if (Object.prototype.isPrototypeOf.call(value, Error)) return value;
|
|
56
|
-
let stringified = "[Unable to stringify the thrown value]";
|
|
57
|
-
try {
|
|
58
|
-
stringified = JSON.stringify(value);
|
|
59
|
-
} catch (e) {
|
|
60
|
-
console.error(e);
|
|
61
|
-
}
|
|
62
|
-
const error = new Error(`This value was thrown as is, not through an Error: ${stringified}`);
|
|
63
|
-
return error;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
67
|
export {
|
|
68
|
+
ensureError,
|
|
67
69
|
isDisabledByEnv,
|
|
68
70
|
defaultConfig,
|
|
69
|
-
mergeConfig
|
|
70
|
-
ensureError
|
|
71
|
+
mergeConfig
|
|
71
72
|
};
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
73
|
+
//# sourceMappingURL=chunk-TPZBZWEN.js.map
|