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

@fnel/angular

v1.0.0

Published

Angular SDK for fnel funnel tracking

Readme

@fnel/angular

Angular SDK for fnel funnel tracking. This package provides Angular services for easy integration of fnel tracking into your Angular applications.

Features

  • 🚀 Easy Integration: Simple service injection pattern with Angular dependency injection
  • 🔄 Auto-initialization: Automatically loads and initializes the fnel SDK
  • 📱 Angular Ready: Built specifically for Angular with proper lifecycle management
  • 🎯 Funnel Tracking: Dedicated service for funnel step tracking
  • 💾 State Management: Reactive state management with RxJS observables
  • 🛡️ TypeScript: Full TypeScript support with comprehensive types
  • 🔧 Debug Support: Access to debug information and SDK state

Installation

npm install @fnel/angular
# or
yarn add @fnel/angular
# or
pnpm add @fnel/angular

Quick Start

1. Initialize the service in your app component

import { Component, OnInit } from '@angular/core';
import { FnelService } from '@fnel/angular';

@Component({
  selector: 'app-root',
  template: '<router-outlet></router-outlet>'
})
export class AppComponent implements OnInit {
  constructor(private fnelService: FnelService) {}

  async ngOnInit() {
    await this.fnelService.initialize({
      apiToken: 'your-api-token-here',
      autoInit: true,
      onInit: (result) => console.log('Initialized:', result),
      onError: (error) => console.error('Error:', error)
    });
  }
}

2. Use the tracking service in your components

import { Component, OnInit } from '@angular/core';
import { FunnelTrackingService } from '@fnel/angular';

@Component({
  selector: 'app-landing-page',
  template: '<div>Welcome to our landing page!</div>'
})
export class LandingPageComponent implements OnInit {
  constructor(private funnelTracking: FunnelTrackingService) {}

  async ngOnInit() {
    if (this.funnelTracking.isInitialized) {
      await this.funnelTracking.trackLandingPage('abc123def', {
        pageTitle: 'Landing Page',
        referrer: document.referrer
      });
    }
  }
}

API Reference

FnelService

The main service that initializes and manages the fnel SDK.

Methods

  • initialize(config: FnelServiceConfig): Promise<FnelInitResult> - Initialize the SDK
  • track(event: FnelEvent): Promise<FnelTrackResult> - Track a custom event
  • version(): string - Get SDK version
  • getUserId(): string | null - Get current user ID
  • isInitializedCheck(): boolean - Check if SDK is initialized
  • getQueueLength(): number - Get current queue length
  • clearQueue(): void - Clear the tracking queue
  • clearStorage(): void - Clear stored data
  • reset(): void - Reset the SDK state

Properties

  • isInitialized: boolean - Whether the SDK is initialized
  • userId: string | null - Current user ID
  • isLoading: boolean - Whether initialization is in progress

Observables

  • isInitialized$: Observable<boolean> - Observable for initialization state
  • userId$: Observable<string | null> - Observable for user ID changes
  • isLoading$: Observable<boolean> - Observable for loading state

FunnelTrackingService

A specialized service for tracking funnel steps with convenience methods.

Methods

  • trackStep(funnelId: string, step: number, stepName?: string, additionalData?: Record<string, any>): Promise<FnelTrackResult>
  • trackLandingPage(funnelId: string, additionalData?: Record<string, any>): Promise<FnelTrackResult>
  • trackConversion(funnelId: string, additionalData?: Record<string, any>): Promise<FnelTrackResult>
  • trackCustomStep(funnelId: string, step: number, stepName: string, additionalData?: Record<string, any>): Promise<FnelTrackResult>

FnelServiceConfig

Configuration interface for the FnelService.

interface FnelServiceConfig {
  apiToken: string;           // Required: Your fnel API token
  autoInit?: boolean;         // Optional: Auto-initialize on service creation (default: false)
  onInit?: (result: FnelInitResult) => void;    // Optional: Success callback
  onError?: (error: Error) => void;             // Optional: Error callback
}

FnelEvent

Event interface for tracking.

interface FnelEvent {
  name: string;      // Event name (e.g., 'landing_page', 'signup_form')
  step: number;      // Step number in the funnel
  funnel: string;    // Funnel identifier
  [key: string]: any; // Additional custom data
}

Advanced Usage

Reactive State Management

The service provides RxJS observables for reactive state management:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { FnelService } from '@fnel/angular';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-analytics',
  template: `
    <div *ngIf="isInitialized$ | async">
      User ID: {{ userId$ | async }}
      <button (click)="trackEvent()">Track Event</button>
    </div>
  `
})
export class AnalyticsComponent implements OnInit, OnDestroy {
  isInitialized$ = this.fnelService.isInitialized$;
  userId$ = this.fnelService.userId$;
  private destroy$ = new Subject<void>();

  constructor(private fnelService: FnelService) {}

  ngOnInit() {
    // Subscribe to state changes
    this.fnelService.isInitialized$
      .pipe(takeUntil(this.destroy$))
      .subscribe(isInitialized => {
        if (isInitialized) {
          console.log('SDK is ready for tracking');
        }
      });
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }

  async trackEvent() {
    await this.fnelService.track({
      name: 'button_click',
      step: 2,
      funnel: 'main_funnel',
      buttonId: 'track_event_btn'
    });
  }
}

Error Handling

import { Component, OnInit } from '@angular/core';
import { FnelService } from '@fnel/angular';

@Component({
  selector: 'app-root',
  template: '<router-outlet></router-outlet>'
})
export class AppComponent implements OnInit {
  constructor(private fnelService: FnelService) {}

  async ngOnInit() {
    try {
      await this.fnelService.initialize({
        apiToken: 'your-api-token-here',
        onError: (error) => {
          console.error('Fnel initialization failed:', error);
          // Handle error appropriately (show user message, retry, etc.)
        }
      });
    } catch (error) {
      console.error('Failed to initialize fnel:', error);
    }
  }
}

Custom Tracking

import { Component } from '@angular/core';
import { FnelService } from '@fnel/angular';

@Component({
  selector: 'app-custom-tracking',
  template: '<button (click)="trackCustomEvent()">Custom Event</button>'
})
export class CustomTrackingComponent {
  constructor(private fnelService: FnelService) {}

  async trackCustomEvent() {
    try {
      const result = await this.fnelService.track({
        name: 'custom_user_action',
        step: 5,
        funnel: 'user_onboarding',
        action: 'button_click',
        timestamp: Date.now(),
        userAgent: navigator.userAgent
      });
      
      console.log('Event tracked:', result);
    } catch (error) {
      console.error('Failed to track event:', error);
    }
  }
}

Testing

The services are designed to be easily testable with Angular's testing utilities:

import { TestBed } from '@angular/core/testing';
import { FnelService } from '@fnel/angular';

describe('FnelService', () => {
  let service: FnelService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [FnelService]
    });
    service = TestBed.inject(FnelService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

Browser Support

This package supports all modern browsers and includes proper SSR (Server-Side Rendering) support for Angular Universal applications.

License

MIT