Angular SDK
Angular services and directives for Entrolytics
Angular SDK
The @entrolytics/angular-sdk package provides Angular services, directives, and dependency injection for tracking analytics in Angular 16+ applications.
Installation
pnpm add @entrolytics/angular-sdkQuick Start
Import Module
Add EntrolyticsModule to your app module:
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { EntrolyticsModule } from '@entrolytics/angular-sdk'
import { AppComponent } from './app.component'
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
EntrolyticsModule.forRoot({
websiteId: 'your-website-id',
host: 'https://entrolytics.dev',
autoTrack: true
})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}Add Environment Variables
Create environment files:
export const environment = {
production: false,
entrolytics: {
websiteId: 'your-website-id',
host: 'https://entrolytics.dev'
}
}export const environment = {
production: true,
entrolytics: {
websiteId: 'your-production-website-id',
host: 'https://entrolytics.dev'
}
}Track Events
Use the EntrolyticsService in your components:
import { Component } from '@angular/core'
import { EntrolyticsService } from '@entrolytics/angular-sdk'
@Component({
selector: 'app-signup',
template: ` <button (click)="handleSignup()">Sign Up</button> `
})
export class SignupComponent {
constructor(private entrolytics: EntrolyticsService) {}
handleSignup() {
this.entrolytics.track('signup', {
plan: 'pro',
source: 'landing-page'
})
}
}Use Tracking Directive
Add the entrolyticsTrack directive to elements:
<button
entrolyticsTrack="button_click"
[entrolyticsProperties]="{ button_name: 'Sign Up', location: 'header' }"
(click)="handleClick()"
>
Sign Up
</button>Configuration
EntrolyticsModule Options
interface EntrolyticsConfig {
/** Website ID (required) */
websiteId: string
/** Link ID for link tracking */
linkId?: string
/** Pixel ID for conversion tracking */
pixelId?: string
/** Custom analytics host URL */
host?: string
/** Auto-track page views (default: true) */
autoTrack?: boolean
/** Use edge-optimized endpoints (default: true) */
useEdgeRuntime?: boolean
/** Tag for A/B testing */
tag?: string
/** Restrict to specific domains */
domains?: string[]
/** Strip query params from URLs */
excludeSearch?: boolean
/** Strip hash fragments from URLs */
excludeHash?: boolean
/** Honor Do Not Track */
respectDnt?: boolean
/** Disable on localhost */
ignoreLocalhost?: boolean
}Runtime Configuration
The useEdgeRuntime option controls which collection endpoint is used:
Edge Runtime (default) - Optimized for speed and global distribution:
EntrolyticsModule.forRoot({
websiteId: 'your-website-id',
useEdgeRuntime: true // or omit (default)
})- Latency: Sub-50ms response times globally
- Best for: Production apps, globally distributed users
- Endpoint: Uses
/api/send-nativefor edge-to-edge communication - Limitations: No ClickHouse export, basic geo data
Node.js Runtime - Full-featured with advanced capabilities:
EntrolyticsModule.forRoot({
websiteId: 'your-website-id',
useEdgeRuntime: false
})- Features: Full ClickHouse export, advanced geo data, custom events
- Best for: Development, analytics-heavy applications
- Endpoint: Uses
/api/sendfor full-featured processing - Capabilities: Complete analytics feature set
API Reference
EntrolyticsService
The main service for tracking events and managing configuration.
Methods
class EntrolyticsService {
/** Track a custom event */
track(event: string, properties?: Record<string, any>): Promise<void>
/** Track a page view */
page(url?: string, properties?: Record<string, any>): Promise<void>
/** Identify a user */
identify(userId: string, traits?: Record<string, any>): Promise<void>
/** Set user properties */
setUserProperties(properties: Record<string, any>): Promise<void>
/** Reset the user session */
reset(): void
/** Get current configuration */
getConfig(): EntrolyticsConfig
/** Update configuration */
updateConfig(config: Partial<EntrolyticsConfig>): void
}Directives
entrolyticsTrack
Automatically track events when elements are clicked.
<!-- Basic usage -->
<button entrolyticsTrack="button_click">Click me</button>
<!-- With properties -->
<button
entrolyticsTrack="button_click"
[entrolyticsProperties]="{ button_name: 'Sign Up' }"
>
Sign Up
</button>
<!-- With custom event handler -->
<button
entrolyticsTrack="button_click"
[entrolyticsProperties]="{ button_name: 'Sign Up' }"
(click)="customHandler()"
>
Sign Up
</button>entrolyticsTrackOnce
Track an event only once per session.
<button entrolyticsTrackOnce="feature_discovery">Discover Features</button>entrolyticsTrackVisible
Track when an element becomes visible in the viewport.
<div
entrolyticsTrackVisible="banner_view"
[entrolyticsProperties]="{ banner_id: 'summer_sale' }"
>
Summer Sale Banner
</div>Advanced Usage
Custom Interceptors
Create HTTP interceptors to automatically track API calls:
import { Injectable } from '@angular/core'
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'
import { EntrolyticsService } from '@entrolytics/angular-sdk'
@Injectable()
export class AnalyticsInterceptor implements HttpInterceptor {
constructor(private entrolytics: EntrolyticsService) {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
// Track API calls
this.entrolytics.track('api_call', {
method: req.method,
url: req.url,
endpoint: req.url.split('/').pop()
})
return next.handle(req)
}
}Register the interceptor:
import { HTTP_INTERCEPTORS } from '@angular/common/http'
@NgModule({
// ...
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AnalyticsInterceptor,
multi: true
}
]
})
export class AppModule {}Route Tracking
Automatically track page views on route changes:
import { NavigationEnd, Router } from '@angular/router'
import { EntrolyticsService } from '@entrolytics/angular-sdk'
import { filter } from 'rxjs/operators'
@NgModule({
// ...
})
export class AppRoutingModule {
constructor(
private router: Router,
private entrolytics: EntrolyticsService
) {
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd))
.subscribe((event: NavigationEnd) => {
this.entrolytics.page(event.urlAfterRedirects)
})
}
}Custom Guards
Create guards that track authentication events:
import { Injectable } from '@angular/core'
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router'
import { EntrolyticsService } from '@entrolytics/angular-sdk'
@Injectable({
providedIn: 'root'
})
export class AnalyticsGuard implements CanActivate {
constructor(private entrolytics: EntrolyticsService) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
this.entrolytics.track('page_access', {
route: state.url,
timestamp: new Date().toISOString()
})
return true
}
}Testing
Unit Testing Services
import { TestBed } from '@angular/core/testing'
import { EntrolyticsService } from '@entrolytics/angular-sdk'
import { SignupService } from './signup.service'
describe('SignupService', () => {
let service: SignupService
let entrolyticsSpy: jasmine.SpyObj<EntrolyticsService>
beforeEach(() => {
const spy = jasmine.createSpyObj('EntrolyticsService', ['track'])
TestBed.configureTestingModule({
providers: [
SignupService,
{ provide: EntrolyticsService, useValue: spy }
])
service = TestBed.inject(SignupService)
entrolyticsSpy = TestBed.inject(EntrolyticsService) as jasmine.SpyObj<EntrolyticsService>
})
it('should track signup event', () => {
service.handleSignup()
expect(entrolyticsSpy.track).toHaveBeenCalledWith('signup', {
plan: 'pro',
timestamp: jasmine.any(String)
})
})
})Testing Directives
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { By } from '@angular/platform-browser'
import { EntrolyticsModule } from '@entrolytics/angular-sdk'
import { TestComponent } from './test.component'
describe('TrackDirective', () => {
let component: TestComponent
let fixture: ComponentFixture<TestComponent>
let entrolyticsSpy: jasmine.SpyObj<EntrolyticsService>
beforeEach(() => {
const spy = jasmine.createSpyObj('EntrolyticsService', ['track'])
TestBed.configureTestingModule({
declarations: [TestComponent],
imports: [EntrolyticsModule],
providers: [{ provide: EntrolyticsService, useValue: spy }]
})
fixture = TestBed.createComponent(TestComponent)
component = fixture.componentInstance
entrolyticsSpy = TestBed.inject(
EntrolyticsService
) as jasmine.SpyObj<EntrolyticsService>
fixture.detectChanges()
})
it('should track click event', () => {
const button = fixture.debugElement.query(By.css('button'))
button.nativeElement.click()
expect(entrolyticsSpy.track).toHaveBeenCalledWith('button_click', {
button_name: 'Test Button'
})
})
})Troubleshooting
Migration from v1
If you're migrating from the old Angular SDK:
// Old v1 syntax
import { EntrolyticsService } from '@entrolytics/angular-sdk-v1'
// New v2 syntax
import { EntrolyticsModule, EntrolyticsService } from '@entrolytics/angular-sdk'
// Old configuration
EntrolyticsService.init('website-id')
// New configuration
EntrolyticsModule.forRoot({
websiteId: 'website-id',
autoTrack: true
})See the migration steps above for detailed upgrade instructions.
Angular SDK for Entrolytics - First-party growth analytics for the edge