npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@plainapps/analytics-angular

v1.0.2

Published

Angular service and module for Plain Web Analytics - privacy-focused, cookie-free analytics

Readme

@plainapps/analytics-angular

Angular service, module, and directives for Plain Web Analytics - privacy-focused, cookie-free web analytics.

Features

  • 🔒 Privacy-first - No cookies, no personal data collection
  • 🎯 Angular-native - Service, module, and directives
  • 📦 Lightweight - Minimal bundle size impact
  • 🔄 Auto route tracking - Automatic pageview tracking with Angular Router
  • Declarative directives - Track events and goals declaratively
  • 📱 SSR compatible - Works with Angular Universal
  • 🎨 Standalone components - Full support for Angular 14+ standalone API

Installation

npm install @plainapps/analytics-angular @plainapps/analytics-core
# or
yarn add @plainapps/analytics-angular @plainapps/analytics-core
# or
pnpm add @plainapps/analytics-angular @plainapps/analytics-core

Quick Start

Using NgModule (Traditional)

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { PlainAnalyticsModule } from '@plainapps/analytics-angular';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    RouterModule.forRoot([/* your routes */]),
    PlainAnalyticsModule.forRoot({
      siteId: 'pwa_site_abc123', // Your site key from dashboard
      autoPageview: true,        // Track initial pageview
      trackRouteChanges: true,   // Track Angular route changes
      debug: false               // Enable console logging in dev
    })
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Using Standalone API (Angular 14+)

// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { providePlainAnalytics } from '@plainapps/analytics-angular';

import { AppComponent } from './app.component';
import { routes } from './app.routes';

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes),
    providePlainAnalytics({
      siteId: 'pwa_site_abc123',
      autoPageview: true,
      trackRouteChanges: true
    })
  ]
});

Usage

Using the Service

import { Component } from '@angular/core';
import { PlainAnalyticsService } from '@plainapps/analytics-angular';

@Component({
  selector: 'app-signup',
  template: `
    <form (ngSubmit)="onSubmit()">
      <input [(ngModel)]="email" name="email" placeholder="Email" />
      <button type="submit">Sign Up</button>
    </form>
  `
})
export class SignupComponent {
  email = '';

  constructor(private analytics: PlainAnalyticsService) {}

  onSubmit() {
    // Track custom event
    this.analytics.trackEvent('signup_attempt', {
      source: 'landing_page'
    });

    // After successful signup
    this.analytics.trackGoal('signup', {
      revenue: 0,
      properties: { plan: 'free' }
    });
  }
}

Using Directives

Import the directives in your component or module:

// With standalone components
import { Component } from '@angular/core';
import { TrackEventDirective, TrackGoalDirective } from '@plainapps/analytics-angular';

@Component({
  selector: 'app-pricing',
  standalone: true,
  imports: [TrackEventDirective, TrackGoalDirective],
  template: `
    <!-- Track click events -->
    <button paTrackEvent="view_pricing">View Pricing</button>
    
    <!-- Track with properties -->
    <button 
      paTrackEvent="select_plan" 
      [paEventProperties]="{ plan: 'pro', price: 1000 }">
      Select Pro Plan
    </button>
    
    <!-- Track goals -->
    <button paTrackGoal="purchase" [paGoalRevenue]="9900">
      Buy Now ($99)
    </button>
    
    <!-- Track on custom events -->
    <input 
      paTrackEvent="search_focus" 
      paEventOn="focus"
      placeholder="Search..." />
  `
})
export class PricingComponent {}

Track Element Visibility

import { Component } from '@angular/core';
import { TrackVisibleDirective } from '@plainapps/analytics-angular';

@Component({
  selector: 'app-landing',
  standalone: true,
  imports: [TrackVisibleDirective],
  template: `
    <!-- Track when section becomes visible -->
    <section 
      paTrackVisible="pricing_section_viewed"
      [paVisibleProperties]="{ page: 'landing' }">
      <h2>Pricing</h2>
      <!-- ... -->
    </section>

    <!-- Track with custom threshold -->
    <div 
      paTrackVisible="cta_visible"
      [paVisibleThreshold]="0.75"
      [paVisibleOnce]="true">
      Call to Action
    </div>
  `
})
export class LandingComponent {}

API Reference

PlainAnalyticsModule

forRoot(config)

Configure analytics for the root module.

PlainAnalyticsModule.forRoot({
  siteId: string;           // Required: Your site key
  apiEndpoint?: string;     // Custom API endpoint
  autoPageview?: boolean;   // Track initial pageview (default: true)
  hashMode?: boolean;       // Track hash changes (default: false)
  debug?: boolean;          // Enable debug logging (default: false)
  trackRouteChanges?: boolean; // Auto-track route changes (default: true)
})

forChild()

Import in lazy-loaded modules (uses root config).

providePlainAnalytics(config)

Standalone provider function with same config options as forRoot().

PlainAnalyticsService

| Method | Description | |--------|-------------| | init(config) | Manual initialization (if not using module config) | | trackPageview(url?) | Track a pageview | | trackEvent(name, properties?) | Track a custom event | | trackGoal(goalId, options?) | Track a goal conversion | | setEnabled(enabled) | Enable/disable tracking | | isInitialized() | Check if initialized | | isEnabled() | Check if tracking is enabled | | getConfig() | Get current configuration |

Directives

TrackEventDirective

| Input | Type | Default | Description | |-------|------|---------|-------------| | paTrackEvent | string | - | Event name (required) | | paEventProperties | object | - | Custom properties | | paEventOn | string | 'click' | DOM event to listen for |

TrackGoalDirective

| Input | Type | Default | Description | |-------|------|---------|-------------| | paTrackGoal | string | - | Goal ID (required) | | paGoalRevenue | number | - | Revenue in cents | | paGoalProperties | object | - | Custom properties | | paGoalOn | string | 'click' | DOM event to listen for |

TrackVisibleDirective

| Input | Type | Default | Description | |-------|------|---------|-------------| | paTrackVisible | string | - | Event name (required) | | paVisibleProperties | object | - | Custom properties | | paVisibleOnce | boolean | true | Track only once | | paVisibleThreshold | number | 0.5 | Visibility threshold (0-1) |

Lazy Loading

For lazy-loaded feature modules, use forChild():

// feature.module.ts
import { NgModule } from '@angular/core';
import { PlainAnalyticsModule } from '@plainapps/analytics-angular';

@NgModule({
  imports: [
    PlainAnalyticsModule.forChild()
  ]
})
export class FeatureModule {}

Angular Universal (SSR)

The library automatically detects server-side rendering and disables tracking during SSR. No additional configuration needed.

Opt-out Support

// Let users opt out of tracking
this.analytics.setEnabled(false);

// Check status
if (this.analytics.isEnabled()) {
  // Tracking is active
}

TypeScript Support

Full TypeScript support with exported types:

import type {
  PlainAnalyticsModuleConfig,
  AnalyticsConfig,
  EventProperties
} from '@plainapps/analytics-angular';

Requirements

  • Angular 12 or higher
  • @plainapps/analytics-core (peer dependency)
  • rxjs 6.0 or higher

Related Packages

License

MIT © Plain Web Analytics