Analytics Events
Lightweight event-based analytics library for tracking user interactions.
Features
- Click tracking with 500ms throttle
- Hover tracking (fires after 1s threshold, reports actual duration)
- View tracking (fires after 5s visibility at 75% threshold)
- Page view tracking (fires immediately, no threshold)
- Custom event tracking via JS (no DOM element needed)
- Session tracking via sessionStorage (persists across page reloads)
- Event batching (10 events or 10s timeout, flushes on page hide)
- Custom attributes via
data-analytics-* - Pluggable destinations: an HTTP backend or Google Analytics 4 (GA4)
Install
npm install @canonical/analytics-eventsUsage
<button data-analytics-click data-analytics-target="signup_btn">
Sign Up
</button>
<div data-analytics-hover data-analytics-target="promo_banner">
Hover me
</div>
<section data-analytics-view data-analytics-target="hero_section">
Track when this section is viewed
</section>
<script type="module">
import { initAnalytics, trackPageView, trackEvent } from '@canonical/analytics-events';
// Send to GA4 via the site's existing Google Tag Manager
initAnalytics({
appName: 'snapcraft',
gtm: true
});
// ...or send to an HTTP backend instead
// initAnalytics({
// appName: 'snapcraft',
// endpoint: 'https://marketplace-analytics.canonical.com/analytics/events'
// });
// Track a page view immediately (HTTP destination; ignored for GA4/GTM)
trackPageView('snap_details_page');
// Track a custom event programmatically (no DOM element needed)
trackEvent('chart_tab_switch', { tab: 'architectures', snap: 'firefox' });
</script>Attributes
| Attribute | Description |
|---|---|
data-analytics-click |
Enable click tracking on element |
data-analytics-hover |
Enable hover tracking on element |
data-analytics-view |
Enable view tracking on element |
data-analytics-view-threshold |
Visibility ratio to trigger view (default: 0.75) |
data-analytics-target |
Identifier for the element (required) |
data-analytics-* |
Custom attributes included in payload |
API
initAnalytics(options)
Initializes all declarative tracking (click, hover, view) and configures the destination.
| Option | Type | Description |
|---|---|---|
appName |
string |
Application identifier (e.g. "snapcraft") |
endpoint |
string |
URL to POST event batches to (HTTP backend) |
gtm |
boolean |
Send to GA4 via an existing GTM container |
Provide one destination. Precedence is gtm -> endpoint; if none is set, declarative tracking is not initialized and events are not delivered.
Destinations
The package can deliver events to different destinations:
- HTTP backend (
endpoint) — batches events (10 events or 10s) and POSTs them vianavigator.sendBeacon/fetch. The payload is the structure below. - Google Analytics 4 via GTM (
gtm: true) — pushes each event onto the page's existingdataLayeras{ event: "analytics_event", ga_event_name, ...params }. The site's Google Tag Manager container then forwards them to GA4. Configure GTM with a trigger on theanalytics_eventcustom event and a GA4 event tag whose event name is thega_event_namedata-layer variable. This reuses the site's existing GTM/GA setup — no second Google loader.
How events map to GA4
| Event type | GA4 event name | Notes |
|---|---|---|
page_view |
— | Not sent; GA4 collects page views automatically |
custom |
the target value |
e.g. chart_tab_switch |
click |
ui_click |
target is sent as a parameter |
view |
ui_view |
target is sent as a parameter |
hover |
ui_hover |
target is sent as a parameter |
Page views use GA4's automatic page-view tracking (enhanced measurement) —
the package does not send its own, and the GA4/GTM destination ignores
page_view events (including those from trackPageView). Declarative types are
prefixed (ui_click, etc.) to avoid
clashing with GA4's built-in event names. Event and parameter names are
truncated to GA4's limits (names <= 40 chars, string values <= 100 chars).
Parameters
All event attributes are forwarded to GA4 as event parameters (alongside
event_type and app_name). Only the package's internal fields — session_id
and url — are not sent (GA4 has its own session model and captures
page_location automatically).
The package is intentionally generic: it does not filter application-specific fields. If a consuming app collects high-cardinality or sensitive attributes (e.g. free-text queries, per-request IDs) that should not go to GA4, it is responsible for not attaching them on the GA4 destination.
trackPageView(target)
Fires a page_view event immediately. Use this for tracking page visits where you need every visit counted regardless of how quickly the user navigates away.
| Parameter | Type | Description |
|---|---|---|
target |
string |
Identifier for the page (e.g. "snap_details_page") |
trackEvent(target, attributes?)
Fires a custom event programmatically from JavaScript. Use this when you need to track interactions that can't be captured with HTML data-analytics-* attributes (e.g. dynamic UI changes, JS-driven actions, form submissions).
| Parameter | Type | Description |
|---|---|---|
target |
string |
Identifier for the event (e.g. "chart_tab_switch") |
attributes |
Record<string, string | number> |
Optional key-value pairs sent with the event |
// ES module import
import { trackEvent } from '@canonical/analytics-events';
trackEvent('video_play', { video_id: 'intro', duration: 120 });
// Global (script tag)
window.Analytics.trackEvent('filter_applied', { category: 'games' });Payload Structure
This is the batch payload sent to the HTTP endpoint destination. (For GA4, see
How events map to GA4 above.)
{
app_name: "snapcraft",
events: [
{
event_type: "click" | "hover" | "view" | "page_view" | "custom",
session_id: "session_abc123...",
target: "signup_btn",
url: "https://example.com/page",
attributes: {
// custom data-analytics-* attributes
duration_ms: 2500, // hover and view only
visibility_ratio: 0.85 // view only
}
}
]
}Development
npm install
npm run build # Build for production
npm run lint # Check code
npm run lint:fix # Fix lint issuesTest App
A demo page is included in test-app/ to test tracking locally.
npm install
npm run build
npm run devOpen http://localhost:3000/test-app/ in your browser. Interact with elements and open the Event Log to see captured events.