ng-track-event-directive
v1.6.3
Published
Declarative Angular directive for analytics event tracking — click, hover, and viewport-view triggers. Adapter-based: works with Mixpanel, Segment, GA4, or any custom backend.
Maintainers
Keywords
Readme
ng-track-event-directive
A lightweight Angular directive that replaces repetitive event listeners with declarative analytics tracking in templates.
Install
npm install ng-track-event-directivePeer dependencies:
@angular/coreand@angular/commonmatching the supported Angular version below
Compatibility
| Package version | Angular support | Status | | --------------- | ------------------------ | -------- | | 1.5.x | Angular 22.x | Current | | 1.4.x | Angular 22.x | Previous | | 1.0.0–1.3.3 | Angular >=21.2.0 <22.0.0 | Previous |
Angular 20 and earlier are not currently supported.
Install the version that matches your Angular application:
# Angular 22
npm install ng-track-event-directive@^1.5.0
# Angular 21.2
npm install [email protected]For Angular 21.2, pin 1.3.3 exactly. A caret range such as ^1.3.3 can select
an Angular-22-only release.
Quick Start
Register a TrackingAdapter
An adapter forwards events from the directive to your analytics provider.
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideTrackingAdapter, type TrackingAdapter } from 'ng-track-event-directive';
const trackingAdapter: TrackingAdapter = {
track(eventName, data) {
console.log('[analytics]', eventName, data);
},
};
export const appConfig: ApplicationConfig = {
providers: [provideTrackingAdapter(trackingAdapter)],
};Use [trackEvent]
Import the standalone directive and expose trackConfig to the template:
import { Component } from '@angular/core';
import { TrackEventDirective, trackConfig } from 'ng-track-event-directive';
@Component({
selector: 'app-root',
standalone: true,
imports: [TrackEventDirective],
template: `
<button [trackEvent]="trackConfig('signup:clicked', { source: 'hero' })">Sign up</button>
<section [trackEvent]="trackConfig('pricing:viewed')">Pricing</section>
`,
})
export class AppComponent {
protected readonly trackConfig = trackConfig;
}Triggers and once
The event-name suffix selects the trigger and its default once behavior.
| Suffix | Trigger | Default once |
| ---------- | --------------------------------- | -------------- |
| :clicked | click | false |
| :hovered | mouse enter | false |
| :viewed | viewport (IntersectionObserver) | true |
Set the third trackConfig argument to override the default:
trackConfig('save:clicked', undefined, true); // first click only
trackConfig('promo:viewed', { campaign: 'summer' }, false); // every viewUse an explicit trigger for standard or custom DOM events that should not be inferred from the analytics event name:
trackConfig('search:focused', { source: 'header' }, { trigger: 'focus' });
trackConfig('dialog:opened', undefined, { trigger: 'dialog-opened', once: true });The explicit trigger takes precedence over any event-name suffix. Only configured data is sent
to the adapter; DOM events and CustomEvent.detail are not forwarded automatically.
TrackConfig
interface TrackConfig<E extends string = string, D = unknown> {
event: E;
data?: D;
trigger?: TrackTrigger;
once?: boolean;
}The trackConfig(event, data?, onceOrOptions?) helper creates this object while preserving event
and payload types. Its third argument accepts the existing once boolean or a TrackOptions
object containing trigger and once.
Provider Examples
Register any of these adapters with provideTrackingAdapter(...) as shown above.
Mixpanel
npm install mixpanel-browserimport mixpanel from 'mixpanel-browser';
import type { TrackingAdapter } from 'ng-track-event-directive';
mixpanel.init('YOUR_PROJECT_TOKEN');
export const mixpanelAdapter: TrackingAdapter = {
track: (eventName, data) => mixpanel.track(eventName, (data ?? {}) as Record<string, unknown>),
};Google Analytics 4
import type { TrackingAdapter } from 'ng-track-event-directive';
declare function gtag(...args: unknown[]): void;
export const ga4Adapter: TrackingAdapter = {
track: (eventName, data) => gtag('event', eventName, (data ?? {}) as Record<string, unknown>),
};Segment
import type { TrackingAdapter } from 'ng-track-event-directive';
declare const analytics: {
track(eventName: string, properties?: Record<string, unknown>): void;
};
export const segmentAdapter: TrackingAdapter = {
track: (eventName, data) => analytics.track(eventName, (data ?? {}) as Record<string, unknown>),
};API
| Export | Purpose |
| ------------------------ | -------------------------------------------- |
| TrackEventDirective | Adds [trackEvent] behavior to an element |
| trackConfig | Creates a typed event configuration |
| provideTrackingAdapter | Registers an adapter |
| TRACKING_ADAPTER | Adapter injection token |
| parseTriggerFromEvent | Resolves a trigger from an event-name suffix |
| TrackConfig | Directive input type |
| TrackOptions | Explicit trigger and one-time options |
| TrackTrigger | Trigger type |
| TrackingAdapter | Analytics adapter contract |
If no adapter is provided, tracking calls are safely ignored.
See the documentation, API reference, and changelog for more.
