Compare commits

...

5 Commits

Author SHA1 Message Date
Aaron 150980929f chore(release): analytics-v0.4.1
vhs / vhs (push) Cancelled after 0s
2025-01-07 13:35:13 -06:00
Aaron bcd906e51b add dependency optimizations automatically 2025-01-07 13:34:52 -06:00
Aaron 00352c2eca Cleanup 2025-01-05 10:34:11 -06:00
Aaron 94027fa82e Update docs 2025-01-05 10:32:57 -06:00
Aaron c2090d64a0 sync deps 2024-12-29 20:42:10 -06:00
7 changed files with 149 additions and 32 deletions
+15 -6
View File
@@ -14,6 +14,7 @@ import { version as i18nVersion } from '../../packages/i18n/package.json';
import { version as autoIconsVersion } from '../../packages/auto-icons/package.json';
import { version as unocssVersion } from '../../packages/unocss/package.json';
import { version as storageVersion } from '../../packages/storage/package.json';
import { version as analyticsVersion } from '../../packages/analytics/package.json';
const title = 'Next-gen Web Extension Framework';
const titleSuffix = ' WXT';
@@ -23,6 +24,14 @@ const ogTitle = `${title}${titleSuffix}`;
const ogUrl = 'https://wxt.dev';
const ogImage = 'https://wxt.dev/social-preview.png';
const otherPackages = {
analytics: analyticsVersion,
'auto-icons': autoIconsVersion,
i18n: i18nVersion,
storage: storageVersion,
unocss: unocssVersion,
};
// https://vitepress.dev/reference/site-config
export default defineConfig({
titleTemplate: `:title${titleSuffix}`,
@@ -97,12 +106,12 @@ export default defineConfig({
'https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md',
),
]),
navItem('Other Packages', [
navItem(`@wxt-dev/storage — ${storageVersion}`, '/storage'),
navItem(`@wxt-dev/auto-icons — ${autoIconsVersion}`, '/auto-icons'),
navItem(`@wxt-dev/i18n${i18nVersion}`, '/i18n'),
navItem(`@wxt-dev/unocss — ${unocssVersion}`, '/unocss'),
]),
navItem(
'Other Packages',
Object.entries(otherPackages).map(([name, version]) =>
navItem(`@wxt-dev/${name}${version}`, `/${name}`),
),
),
]),
],
+1
View File
@@ -0,0 +1 @@
<!--@include: ../packages/analytics/README.md-->
+95
View File
@@ -172,3 +172,98 @@ export default defineAppConfig({
```
Example `AnalyticsProvider` implementations can be found at [`./modules/analytics/providers`](https://github.com/wxt-dev/wxt/tree/main/packages/analytics/modules/analytics/providers).
## User Properties
User ID and properties are stored in `browser.storage.local`. To change this or customize where these values are stored, use the `userId` and `userProperties` config:
```ts
// app.config.ts
import { storage } from 'wxt/storage';
export default defineAppConfig({
analytics: {
userId: storage.defineItem('local:custom-user-id-key'),
userProperties: storage.defineItem('local:custom-user-properties-key'),
},
});
```
To set the values at runtime, use the `identify` function:
```ts
await analytics.identify(userId, userProperties);
```
Alternatively, a common pattern is to use a random string as the user ID. This keeps the actual user information private, while still providing useful metrics in your analytics platform. This can be done very easily using WXT's storage API:
```ts
// app.config.ts
import { storage } from 'wxt/storage';
export default defineAppConfig({
analytics: {
userId: storage.defineItem('local:custom-user-id-key', {
init: () => crypto.randomUUID(),
}),
},
});
```
If you aren't using `wxt` or `@wxt-dev/storage`, you can define custom implementations for the `userId` and `userProperties` config:
```ts
const analytics = createAnalytics({
userId: {
getValue: () => ...,
setValue: (userId) => ...,
}
})
```
## Auto-track UI events
Call `analytics.autoTrack(container)` to automatically track UI events so you don't have to manually add them. Currently it:
- Tracks clicks to elements inside the `container`
In your extension's HTML pages, you'll want to call it with `document`:
```ts
analytics.autoTrack(document);
```
But in content scripts, you usually only care about interactions with your own UI:
```ts
const ui = createIntegratedUi({
// ...
onMount(container) {
analytics.autoTrack(container);
},
});
ui.mount();
```
## Enabling/Disabling
By default, **analytics is disabled**. You can configure how the value is stored (and change the default value) via the `enabled` config:
```ts
// app.config.ts
import { storage } from 'wxt/storage';
export default defineAppConfig({
analytics: {
enabled: storage.defineItem('local:analytics-enabled', {
fallback: true,
}),
},
});
```
At runtime, you can call `setEnabled` to change the value:
```ts
analytics.setEnabled(true);
```
+16 -1
View File
@@ -1,6 +1,11 @@
import 'wxt';
import 'wxt/sandbox';
import { addAlias, addWxtPlugin, defineWxtModule } from 'wxt/modules';
import {
addAlias,
addViteConfig,
addWxtPlugin,
defineWxtModule,
} from 'wxt/modules';
import { relative, resolve } from 'node:path';
import type { AnalyticsConfig } from './types';
@@ -72,5 +77,15 @@ export default defineWxtModule({
// Ensure analytics is initialized in every context, mainly the background.
// TODO: Once there's a way to filter which entrypoints a plugin is applied to, only apply this to the background
addWxtPlugin(wxt, pluginModuleId);
// Fix issues with dependencies
addViteConfig(wxt, () => ({
optimizeDeps: {
// Ensure the "#analytics" import is processed by vite in the background plugin
exclude: ['@wxt-dev/analytics'],
// Ensure the CJS subdependency is preprocessed into ESM
include: ['@wxt-dev/analytics > ua-parser-js'],
},
}));
},
});
+15 -14
View File
@@ -1,13 +1,13 @@
export interface Analytics {
/** Report a page change */
/** Report a page change. */
page: (url: string) => void;
/** Report a custom event */
/** Report a custom event. */
track: (eventName: string, eventProperties?: Record<string, string>) => void;
/** Save information about the user */
/** Save information about the user. */
identify: (userId: string, userProperties?: Record<string, string>) => void;
/** Automatically setup and track user interactions, returning a function to remove any listeners that were setup. */
autoTrack: (root: Document | ShadowRoot | Element) => () => void;
/** Calls `config.enabled.setValue` */
/** Calls `config.enabled.setValue`. */
setEnabled: (enabled: boolean) => void;
}
@@ -21,19 +21,20 @@ export interface AnalyticsConfig {
*/
debug?: boolean;
/**
* Extension version, defaults to `browser.runtime.getManifest().version`.
* Your extension's version, reported alongside events.
* @default browser.runtime.getManifest().version`.
*/
version?: string;
/**
* Configure how the enabled flag is persisted. Defaults to using `""` in local extension storage.
* Configure how the enabled flag is persisted. Defaults to using `browser.storage.local`.
*/
enabled?: AnalyticsStorageItem<boolean>;
/**
* Configure how the user Id is persisted
* Configure how the user Id is persisted. Defaults to using `browser.storage.local`.
*/
userId?: AnalyticsStorageItem<string>;
/**
* Configure how user properties are persisted
* Configure how user properties are persisted. Defaults to using `browser.storage.local`.
*/
userProperties?: AnalyticsStorageItem<Record<string, string>>;
}
@@ -47,11 +48,11 @@ export type AnalyticsProvider = (
analytics: Analytics,
config: AnalyticsConfig,
) => {
/** Upload a page view event */
/** Upload a page view event. */
page: (event: AnalyticsPageViewEvent) => Promise<void>;
/** Upload a custom event */
/** Upload a custom event. */
track: (event: AnalyticsTrackEvent) => Promise<void>;
/** Upload information about the user */
/** Upload information about the user. */
identify: (event: BaseAnalyticsEvent) => Promise<void>;
};
@@ -64,11 +65,11 @@ export interface BaseAnalyticsEvent {
}
export interface AnalyticsEventMetadata {
/** Identifier of the session the event was fired from */
/** Identifier of the session the event was fired from. */
sessionId: number | undefined;
/** `Date.now()` of when the event was reported */
/** `Date.now()` of when the event was reported. */
timestamp: number;
/** `"1920x1080"` */
/** Ex: `"1920x1080"`. */
screen: string | undefined;
/** `document.referrer` */
referrer: string | undefined;
+4 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@wxt-dev/analytics",
"version": "0.4.0",
"version": "0.4.1",
"description": "Add analytics to your web extension",
"repository": {
"type": "git",
@@ -51,12 +51,11 @@
"wxt": ">=0.19.23"
},
"devDependencies": {
"@aklinker1/check": "^1.3.1",
"@aklinker1/check": "^1.4.5",
"@types/chrome": "^0.0.268",
"@types/ua-parser-js": "^0.7.39",
"prettier": "^3.3.2",
"publint": "^0.2.8",
"typescript": "^5.5.2",
"publint": "^0.2.12",
"typescript": "^5.6.3",
"unbuild": "^2.0.0",
"wxt": "workspace:*"
},
+3 -6
View File
@@ -90,7 +90,7 @@ importers:
version: 1.0.40
devDependencies:
'@aklinker1/check':
specifier: ^1.3.1
specifier: ^1.4.5
version: 1.4.5(typescript@5.6.3)
'@types/chrome':
specifier: ^0.0.268
@@ -98,14 +98,11 @@ importers:
'@types/ua-parser-js':
specifier: ^0.7.39
version: 0.7.39
prettier:
specifier: ^3.3.2
version: 3.3.3
publint:
specifier: ^0.2.8
specifier: ^0.2.12
version: 0.2.12
typescript:
specifier: ^5.5.2
specifier: ^5.6.3
version: 5.6.3
unbuild:
specifier: ^2.0.0