Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/analytics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Report analytics events from your web extension extension.
## Supported Analytics Providers

- [Google Analytics 4 (Measurement Protocol)](#google-analytics-4-measurement-protocol)
- [PostHog](#posthog)
- [Umami](#umami)

## Install With WXT
Expand Down Expand Up @@ -120,6 +121,35 @@ export default defineAppConfig({
});
```

### PostHog

[PostHog](https://posthog.com/) is an open source product analytics platform. It supports event tracking, session recording, feature flags, surveys, and more.

In your PostHog project settings, find your **Project API key** and save it to your `.env` file:

```dotenv
WXT_POSTHOG_API_KEY='phc_...'
```

Then add the `posthog` provider to your `<srcDir>/app.config.ts` file:

```ts
import { posthog } from '@wxt-dev/analytics/providers/posthog';

export default defineAppConfig({
analytics: {
providers: [
posthog({
apiKey: import.meta.env.WXT_POSTHOG_API_KEY,
// apiHost defaults to 'https://us.i.posthog.com'.
// Change to 'https://eu.i.posthog.com' for EU Cloud, or your self-hosted URL.
apiHost: 'https://eu.i.posthog.com',
}),
],
},
});
```

### Umami

[Umami](https://umami.is/) is a privacy-first, open source analytics platform.
Expand Down
4 changes: 4 additions & 0 deletions packages/analytics/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineAppConfig } from 'wxt/utils/define-app-config';
import { googleAnalytics4 } from './modules/analytics/providers/google-analytics-4';
import { posthog } from './modules/analytics/providers/posthog';
import { umami } from './modules/analytics/providers/umami';

export default defineAppConfig({
Expand All @@ -10,6 +11,9 @@ export default defineAppConfig({
apiSecret: '...',
measurementId: '...',
}),
posthog({
apiKey: '...',
}),
umami({
apiUrl: 'https://umami.aklinker1.io/api',
domain: 'analytics.wxt.dev',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const googleAnalytics4 =
eventProperties: Record<string, string | undefined> | undefined,
): Promise<void> => {
const url = new URL(
config?.debug ? '/debug/mp/collect' : '/mp/collect',
config.debug ? '/debug/mp/collect' : '/mp/collect',
options.apiUrl ?? 'https://www.google-analytics.com',
);
if (options.apiSecret)
Expand All @@ -38,6 +38,12 @@ export const googleAnalytics4 =
]),
);

if (config.debug) {
console.debug(
'[@wxt-dev/analytics] Sending event to Google Analytics 4:',
{ eventName, eventProperties },
);
}
await fetch(url.href, {
method: 'POST',
body: JSON.stringify({
Expand Down
83 changes: 83 additions & 0 deletions packages/analytics/modules/analytics/providers/posthog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { defineAnalyticsProvider } from '../client';

export interface PostHogProviderOptions {
/** Your PostHog project API key. */
apiKey: string;
/**
* PostHog API host URL.
*
* @default 'https://us.i.posthog.com'
*/
apiHost?: string;
}

export const posthog = defineAnalyticsProvider<PostHogProviderOptions>(
(_, config, options) => {
const apiHost = (options.apiHost ?? 'https://us.i.posthog.com').replace(
/\/$/,
'',
);

const capture = async (
distinctId: string,
event: string,
properties: Record<string, unknown>,
): Promise<void> => {
if (config.debug) {
console.debug('[@wxt-dev/analytics] Sending event to PostHog:', {
event,
properties,
});
}
const body: PostHogCaptureBody = {
api_key: options.apiKey,
distinct_id: distinctId,
event,
properties,
timestamp: new Date().toISOString(),
};
await fetch(`${apiHost}/i/v0/e/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
};

return {
identify: async (event) => {
await capture(event.user.id, '$identify', {
$set: event.user.properties,
});
},
page: async (event) => {
await capture(event.user.id, '$pageview', {
$current_url: event.page.url,
$title: event.page.title,
$session_id: event.meta.sessionId,
$screen: event.meta.screen,
$language: event.meta.language,
$referrer: event.meta.referrer,
$set: event.user.properties,
});
},
track: async (event) => {
await capture(event.user.id, event.event.name, {
...event.event.properties,
$screen: event.meta.screen,
$language: event.meta.language,
$referrer: event.meta.referrer,
$set: event.user.properties,
});
},
};
},
);

/** @see https://posthog.com/docs/api/capture */
interface PostHogCaptureBody {
api_key: string;
distinct_id: string;
event: string;
properties: Record<string, unknown>;
timestamp: string;
}
4 changes: 4 additions & 0 deletions packages/analytics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
"./providers/umami": {
"types": "./dist/providers/umami.d.mts",
"default": "./dist/providers/umami.mjs"
},
"./providers/posthog": {
"types": "./dist/providers/posthog.d.mts",
"default": "./dist/providers/posthog.mjs"
}
},
"module": "./dist/index.mjs",
Expand Down
1 change: 1 addition & 0 deletions packages/analytics/tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default defineConfig({
'providers/google-analytics-4':
'./modules/analytics/providers/google-analytics-4.ts',
'providers/umami': './modules/analytics/providers/umami.ts',
'providers/posthog': './modules/analytics/providers/posthog.ts',
},
deps: {
neverBundle: ['#analytics'],
Expand Down