Skip to content
Closed
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
7 changes: 7 additions & 0 deletions analytics.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"folders": [
{
"path": "examples/using-perfumejs"
}
]
}
8 changes: 8 additions & 0 deletions examples/demo/module/module.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}
117 changes: 117 additions & 0 deletions examples/using-perfumejs/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Analytics Perfume.js Example - Agent Instructions

This is a React example demonstrating how to integrate [Perfume.js](https://github.com/Zizzamia/perfume.js/) (web performance monitoring) with the [Analytics](https://github.com/DavidWells/analytics) library to automatically track and report performance metrics to multiple analytics providers.

## Quick Start

- **Start development**: `npm start` (hot reload on http://localhost:3000)
- **Build for production**: `npm build`
- **Run tests**: `npm test`
- **Deploy to Netlify**: `npm deploy`

## Project Structure & Purpose

This is an **example/demo app**, not a library. The key goal is to demonstrate the pattern:

```
src/
├── App.js # Main app - initializes analytics with perfume.js plugin
├── plugins/
│ ├── perfume.js # Perfume.js integration plugin (tracks Web Vitals)
│ └── custom.js # Simple example of a custom analytics plugin
└── index.js # React entry point
```

## Core Concepts & Patterns

### Analytics Initialization (src/App.js)

The app initializes a centralized `analytics` instance with multiple plugins:

```javascript
const analytics = Analytics({
app: 'my-app',
plugins: [
{ name: 'test-plugin', track: ({ payload }) => { ... } },
customAnalyticsPlugin,
googleAnalytics({ trackingId: '...' }),
perfumePlugin({ category: 'perf', perfume: Perfume })
]
})
```

**Key pattern**: Plugins are composed together. When `analytics.track()` is called, all plugins receive the event.

### Plugin Architecture (src/plugins/)

Plugins follow this interface:

```javascript
{
name: 'plugin-name', // Required: unique identifier
track: ({ payload }) => { ... } // Track events
initialize: ({ instance, config }) => {} // Optional: initialization hook
}
```

**Perfume.js plugin (`perfume.js`)**: Automatically tracks Web Vitals (FP, FCP, LCP, FID, CLS, TBT) and forwards them through analytics to all attached providers.

**Custom plugin (`custom.js`)**: Simple logger example - shows minimal plugin implementation.

### Performance Metrics Tracked

Perfume.js monitors Core Web Vitals:
- **FP** (First Paint)
- **FCP** (First Contentful Paint)
- **LCP** (Largest Contentful Paint)
- **FID** (First Input Delay)
- **CLS** (Cumulative Layout Shift)
- **TBT** (Total Blocking Time)

These are categorized as `lowEndExperience` or `highEndExperience` for segmentation.

## Common Tasks

### Add a new analytics provider

1. Install the provider plugin: `npm install @analytics/[provider-name]`
2. Add to the `plugins` array in `App.js`:
```javascript
providerName({ config: 'values' })
```
3. The provider automatically receives all tracked events (including perfume.js metrics)

### Create a custom analytics plugin

Create a new file in `src/plugins/` following the plugin interface:
- Minimal: just need `name` and `track` function
- Advanced: add `initialize` hook for setup
- Plugin receives all analytics events via the `track` callback

### Debug what's being tracked

Open browser DevTools console:
- The `test-plugin` in App.js logs all events to console
- Each plugin sees the full `payload` with event name, properties, and metadata

### Modify what perfume.js tracks

Edit `src/plugins/perfume.js`:
- `metricNames` array: which metrics to report
- The `analyticsTracker` callback: customize how metrics are formatted and sent
- Note: Metrics are scaled for Google Analytics (integers) - adjust per provider

## Design Decisions

- **Centralized analytics instance** in `App.js`: All tracking goes through one place
- **Plugin composition**: Decoupled providers - add/remove without changing core logic
- **Non-interaction events**: Perfume metrics don't affect bounce rate in GA
- **Value scaling**: CLS values multiplied by 1000 for GA (which requires integers)
- **Device experience segmentation**: Metrics tagged as `lowEndExperience` or `highEndExperience`

## Related Resources

- [Live example app](https://analytics-perfumejs-example.netlify.app/)
- [Perfume.js documentation](https://zizzamia.github.io/perfume/)
- [Analytics library docs](https://github.com/DavidWells/analytics)
- [Example video](https://www.youtube.com/watch?v=9DZAVpAubtQ)
2 changes: 1 addition & 1 deletion site/gatsby-theme-base/package.json
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"gatsby-plugin-react-helmet": "^3.0.2",
"gatsby-plugin-svgr": "^2.0.1",
"less": "^3.9.0",
"lodash": "^4.17.11",
"lodash": "^4.18.1",
"polished": "^2.3.3",
"prop-types": "^15.6.2",
"react": "^16.8.6",
Expand Down
13 changes: 4 additions & 9 deletions site/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10010,15 +10010,10 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=

lodash@^4.11.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0:
version "4.17.14"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==

lodash@^4.17.13, lodash@^4.17.15, lodash@^4.2.1:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
lodash@^4.11.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.18.1, lodash@^4.2.1, lodash@^4.3.0:
version "4.18.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.18.1.tgz#ff2b66c1f6326d59513de2407bf881439812771c"
integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==

log-process-errors@^5.1.1:
version "5.1.2"
Expand Down