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

cuoral-ionic

v0.0.5

Published

Cuoral Ionic Framework Library - Proactive customer success platform with support ticketing, customer intelligence, screen recording, and engagement tools

Readme

Cuoral Ionic Library

Proactive customer success platform integration for Ionic/Capacitor applications. Cuoral provides support ticketing, customer intelligence, screen recording, and comprehensive customer engagement tools.

Features

Customer Support - Integrated support ticketing system
Customer Intelligence - Track and analyze customer behavior automatically
Native Crash Tracking - Capture native Android & iOS crashes
Screen Recording - Native screen recording for issue reproduction
Modal Display - Full-screen modal with floating chat button
TypeScript Support - Full type definitions included
Simple API - Just pass your public key and optional user info
Zero Configuration - Everything handled automatically

Installation

npm install cuoral-ionic

After installing, sync your Capacitor project:

npx cap sync

Platform Setup

Android Setup

The Android plugin automatically declares required permissions. Ensure your AndroidManifest.xml includes:

<!-- Required for support widget and intelligence tracking -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- Required for screen recording with audio -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<!-- Required for screen recording on Android 9 and below -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                 android:maxSdkVersion="28" />

Note: These permissions are automatically added by Capacitor when you run npx cap sync android. The INTERNET permission is auto-granted by the system. RECORD_AUDIO requires user approval at runtime.

iOS Setup

Add to your Info.plist:

<!-- Required for screen recording with audio -->
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone to record audio with screen recordings</string>

Note: Screen recording permission is requested automatically by iOS when recording starts. No additional permissions are needed for crash tracking or intelligence features.

Quick Start

Option 1: Modal with Floating Button (Recommended)

The easiest way to integrate Cuoral - displays a floating chat button that opens the widget in a full-screen modal.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Cuoral } from 'cuoral-ionic';

@Component({
  selector: 'app-home',
  template: `
    <ion-content>
      <!-- Your app content -->
      <h1>Welcome to Support</h1>

      <!-- Optional: Custom button to open widget -->
      <ion-button (click)="openSupport()"> Contact Support </ion-button>
    </ion-content>
  `,
})
export class HomePage implements OnInit, OnDestroy {
  private cuoral: Cuoral;

  constructor() {
    this.cuoral = new Cuoral({
      publicKey: 'your-public-key-here',
      email: '[email protected]', // Optional
      firstName: 'John', // Optional
      lastName: 'Doe', // Optional
      showFloatingButton: true, // Show floating chat button
      useModal: true, // Use modal display mode
    });
  }

  ngOnInit() {
    this.cuoral.initialize();
  }

  ngOnDestroy() {
    this.cuoral.destroy();
  }

  // Open modal programmatically
  openSupport() {
    this.cuoral.openModal();
  }
}

Features:

  • 🎈 Floating blue chat button in bottom-right corner
  • 📱 Opens widget in full-screen modal with small margins
  • ❌ Close button in top-right
  • 🎨 Smooth animations and transitions
  • 🖱️ Click backdrop to close

Option 2: Embedded Iframe - Not Recommended

For more control over widget placement:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { Cuoral } from 'cuoral-ionic';

@Component({
  selector: 'app-support',
  template: `
    <ion-content>
      <iframe [src]="widgetUrl" style="width: 100%; height: 600px; border: none;"> </iframe>
    </ion-content>
  `,
})
export class SupportPage implements OnInit, OnDestroy {
  widgetUrl: SafeResourceUrl;
  private cuoral: Cuoral;

  constructor(private sanitizer: DomSanitizer) {
    this.cuoral = new Cuoral({
      publicKey: 'your-public-key-here',
      useModal: false, // Disable modal mode
    });

    const url = this.cuoral.getWidgetUrl();
    this.widgetUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }

  ngOnInit() {
    this.cuoral.initialize();
  }

  ngOnDestroy() {
    this.cuoral.destroy();
  }
}

Enable Page View Tracking (One-Time Setup)

To automatically track page views, add router tracking to your app.component.ts (or main app component):

import { Component } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { Cuoral } from 'cuoral-ionic';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
})
export class AppComponent {
  private cuoral: Cuoral;

  constructor(private router: Router) {
    this.cuoral = new Cuoral({
      publicKey: 'your-public-key-here',
      email: '[email protected]',
      firstName: 'John',
      lastName: 'Doe',
    });
  }

  async ngOnInit() {
    // Initialize Cuoral (intelligence auto-enabled from dashboard)
    await this.cuoral.initialize();

    // Track all page navigation automatically
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        this.cuoral.trackPageView(event.url);
      }
    });
  }
}

That's it! All page views are now automatically tracked. Console errors, network errors, and native crashes are tracked with zero additional setup.

User Logout & Session Management

When users log out, properly clear and end the session before destroying the Cuoral instance:

async logout() {
  // Step 1: Clear and end the session
  await this.cuoral.clearSession();

  // Step 2: Destroy the Cuoral instance
  this.cuoral.destroy();

  // Step 3: Your logout logic
  // Navigate to login, clear user data, etc.
}

When a different user logs in on the same device, create a fresh Cuoral instance:

async login(email: string, firstName: string, lastName: string) {
  // Create new instance for the new user
  this.cuoral = new Cuoral({
    publicKey: 'your-public-key-here',
    email: email,
    firstName: firstName,
    lastName: lastName,
  });

  // Initialize for new user
  await this.cuoral.initialize();
}

Important Notes:

  • clearSession() marks the session as ended on the backend
  • destroy() cleans up local resources
  • Always call clearSession() before destroy() on logout
  • Create a new Cuoral instance for each user login
  • Email, first name, and last name are all required for identified users

Push Notifications

Cuoral integrates seamlessly with your existing push notification system using webhooks. When an agent sends a message, Cuoral sends a webhook to your backend, allowing you to send push notifications to users when the widget is closed.

How it works:

  1. Track widget state in your app (open/closed)
  2. Configure webhooks in your Cuoral dashboard
  3. Receive webhook when agent sends message
  4. Send FCM/APNs push if widget is closed

Example Implementation:

export class MyApp {
  private isCuoralWidgetOpen = false;

  // When user opens support
  openSupport() {
    this.isCuoralWidgetOpen = true;
    this.cuoral.openModal();
  }

  // When user closes support
  closeSupport() {
    this.isCuoralWidgetOpen = false;
    this.cuoral.closeModal();
  }

  // Handle incoming push notifications (your existing FCM handler)
  async handlePushNotification(message: any) {
    if (message.data.type === 'cuoral_message') {
      // Don't show notification if widget is already open
      if (this.isCuoralWidgetOpen) {
        return; // User already sees the message
      }

      // Show notification to user
      await this.showNotification({
        title: 'New message from Support',
        body: message.data.text,
      });

      // When user taps notification, open widget
      this.openSupport();
    }
  }
}

Setup:

  1. Configure your webhook URL in Cuoral Dashboard → Settings → Webhooks
  2. Cuoral sends webhooks for all new messages
  3. Your backend decides whether to send push based on your app's state
  4. User taps notification → your app calls cuoral.openModal()

This approach works with your existing FCM/APNs setup - no additional SDK configuration needed!

Configuration

CuoralOptions

interface CuoralOptions {
  publicKey: string; // Required: Your Cuoral public key
  email?: string; // Optional: User email
  firstName?: string; // Optional: User first name
  lastName?: string; // Optional: User last name
  debug?: boolean; // Optional: Enable debug logging (default: false)
  widgetBaseUrl?: string; // Optional: Custom widget URL (default: CDN)
  showFloatingButton?: boolean; // Optional: Show floating chat button (default: true)
  useModal?: boolean; // Optional: Use modal display mode (default: true)
}

Widget URL

By default, the widget loads from https://js.cuoral.com/mobile.html (production CDN).

Production (Default):

new Cuoral({ publicKey: 'your-key' });

Custom URL (Optional):

If you need to use a custom widget URL for testing or self-hosting:

new Cuoral({
  publicKey: 'your-key',
  widgetBaseUrl: 'https://your-domain.com/mobile.html',
});

API Reference

Cuoral Methods

// Initialize Cuoral
cuoral.initialize(): void

// Get widget URL for iframe embedding
cuoral.getWidgetUrl(): string

// Open modal programmatically
cuoral.openModal(): void

// Close modal programmatically
cuoral.closeModal(): void

// Check if modal is open
cuoral.isModalOpen(): boolean

// Clean up resources
cuoral.destroy(): void

What Gets Handled Automatically

  • ✅ Support ticket creation and management
  • ✅ Customer intelligence tracking (page views, errors, network failures)
  • ✅ Native crash tracking (Android & iOS)
  • ✅ Screen recording start/stop
  • ✅ File path conversion for video playback
  • ✅ Communication between widget and native code
  • ✅ Video upload to Cuoral backend
  • ✅ State management
  • ✅ Permissions handling

Intelligence Features (Backend-Controlled)

Intelligence tracking is automatically enabled/disabled from your Cuoral dashboard. When enabled, the library automatically captures:

  • Page Views - Track navigation (requires one-time router setup, see INTELLIGENCE.md)
  • Console Errors - JavaScript errors and unhandled exceptions
  • Network Errors - Failed API calls (4xx, 5xx responses)
  • Native Crashes - Native Android (Java/Kotlin) and iOS (Swift/Objective-C) crashes

For detailed intelligence setup and features, see INTELLIGENCE.md

Troubleshooting

Recording doesn't start

Check iOS permissions:

  • Verify NSMicrophoneUsageDescription is in Info.plist
  • System will prompt user automatically on first recording

Enable debug mode:

new Cuoral({
  publicKey: 'your-key',
  debug: true, // See console logs
});

Widget not appearing

Modal mode:

  • Make sure you called cuoral.initialize()
  • Check that useModal: true is set (default)
  • Look for the blue floating button in bottom-right

Iframe mode:

  • Verify widgetUrl is properly sanitized with DomSanitizer
  • Check browser console for CORS errors
  • Ensure iframe has proper dimensions in CSS

Build errors

iOS Pod Issues:

cd ios
pod deintegrate
pod install
cd ..
npx cap sync ios

Clean build:

rm -rf node_modules dist
npm install
npx cap sync

Support

  • 📧 Email: [email protected]
  • 📖 Docs: https://docs.cuoral.com
  • 🐛 Issues: https://github.com/cuoral/cuoral-ionic/issues

License

MIT License - see LICENSE file


Built with ❤️ by Cuoral