npm.io
1.35.2 • Published 4d ago

@active-reach/web-sdk

Licence
MIT
Version
1.35.2
Deps
0
Size
4.4 MB
Vulns
0
Weekly
0

@active-reach/web-sdk

Web SDK for Active Reach Intelligence — lightweight event tracking, identity resolution, in-app messaging (overlays, embedded cards, interactive widgets), and web push.

12KB gzipped | <1KB async loader | Zero impact on page load


Prerequisites

Before integrating, you need:

  1. Write Key — Retrieve from your Active Reach Intelligence dashboard under Settings > Developer > API Keys.
  2. API Host — Your cell endpoint URL (provided during onboarding).

Note: The write key is a publishable identifier (like a Stripe publishable key). It is safe to include in client-side code. It can only send events — it cannot read data, modify configuration, or access other tenants. Never use your Secret Key in client-side code.


Installation

npm install @active-reach/web-sdk
CDN (Async Loader)

Add this snippet to your <head> tag. The async loader queues all calls until the full SDK loads — zero blocking.

<script>
  !function(){var e=window.aegis=window.aegis||[];if(!e.invoked){e.invoked=!0,e.methods=["init","track","identify","page","group","alias","reset","flush","use","debug","setCell","getCellInfo","getAnonymousId","getUserId","getSessionId","setConsent","grantConsent","denyConsent","hasConsent","getConsentPreferences","onConsentChange"],e.factory=function(t){return function(){var n=Array.prototype.slice.call(arguments);return n.unshift(t),e.push(n),e}};for(var t=0;t<e.methods.length;t++){var n=e.methods[t];e[n]=e.factory(n)}e.load=function(t,n){var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=n&&n.cdnUrl?n.cdnUrl:"https://cdn.activereach.ai/sdk/aegis.min.js",o.onerror=function(){window.console&&console.error("Aegis SDK failed to load")};var r=document.getElementsByTagName("script")[0];r.parentNode.insertBefore(o,r),e._loadOptions={key:t,options:n}},e.SNIPPET_VERSION="1.0.0"}}();

  aegis.load('YOUR_WRITE_KEY');
  aegis.init('YOUR_WRITE_KEY', {
    api_host: 'https://YOUR_CELL.activereach.ai'
  });
</script>

Quick Start

NPM / ES Modules
import aegis from '@active-reach/web-sdk';

await aegis.init('YOUR_WRITE_KEY', {
  api_host: 'https://YOUR_CELL.activereach.ai',
  auto_page_view: true,
});

// Track an event
aegis.track('Purchase Completed', {
  order_id: 'ORD-123',
  revenue: 99.99,
  currency: 'INR',
});

// Identify a user
aegis.identify('user_123', {
  email: 'user@example.com',
  name: 'Priya Sharma',
  plan: 'premium',
});
React
import { AegisProvider, useAegis, useTrackEvent } from '@active-reach/web-sdk/react';

function App() {
  return (
    <AegisProvider
      writeKey="YOUR_WRITE_KEY"
      config={{ api_host: 'https://YOUR_CELL.activereach.ai', auto_page_view: true }}
    >
      <Dashboard />
    </AegisProvider>
  );
}

function Dashboard() {
  const { isReady } = useAegis();
  const trackEvent = useTrackEvent();

  return (
    <button onClick={() => trackEvent('Button Clicked', { button: 'CTA' })}>
      Track Event
    </button>
  );
}
Next.js
// app/providers.tsx
'use client';

import { AegisProvider } from '@active-reach/web-sdk/react';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <AegisProvider
      writeKey={process.env.NEXT_PUBLIC_AEGIS_WRITE_KEY!}
      config={{ api_host: process.env.NEXT_PUBLIC_AEGIS_API_HOST! }}
    >
      {children}
    </AegisProvider>
  );
}

Configuration

await aegis.init('YOUR_WRITE_KEY', {
  // Required
  api_host: string;

  // Batching & Performance
  batch_size?: number;           // default: 10
  batch_interval?: number;       // default: 1000ms

  // Data Capture
  capture_utm?: boolean;         // default: true
  capture_referrer?: boolean;    // default: true
  auto_page_view?: boolean;      // default: false

  // Session
  session_timeout?: number;      // default: 1800000 (30 min)

  // Privacy & Consent
  respect_dnt?: boolean;         // default: true
  enable_consent_mode?: boolean; // default: false
  wait_for_consent?: boolean;    // default: false
  default_consent?: {
    analytics?: boolean;         // default: false
    marketing?: boolean;         // default: false
    functional?: boolean;        // default: true
  };
  integrate_onetrust?: boolean;
  integrate_cookiebot?: boolean;
  integrate_google_consent_mode?: boolean;

  // Cookie
  cross_domain_tracking?: boolean; // default: false
  cookie_domain?: string;
  secure_cookie?: boolean;         // default: true

  // Offline & Retry
  enable_offline_mode?: boolean;   // default: true
  max_offline_events?: number;     // default: 100
  retry_failed_requests?: boolean; // default: true
  max_retries?: number;            // default: 3

  // Regional Cell Selection
  cell_endpoints?: CellEndpoint[];
  preferred_region?: string;
  auto_region_detection?: boolean; // default: true

  // Debug
  debug?: boolean;                 // default: false
});

Core API

aegis.track(eventName, properties?)

Track a custom event.

aegis.track('Product Viewed', {
  product_id: 'SKU-12345',
  product_name: 'Leather Jacket',
  price: 199.99,
  category: 'Outerwear',
});
aegis.identify(userId, traits?)

Identify a user and associate traits.

aegis.identify('user_123', {
  email: 'user@example.com',
  name: 'John Doe',
  plan: 'premium',
});
aegis.page(name?, properties?)

Track a page view.

aegis.page('Product Page', { product_id: 'SKU-12345' });
aegis.group(groupId, traits?)

Associate a user with a group (company, organization).

aegis.group('company_789', {
  name: 'Acme Corp',
  industry: 'Technology',
  employees: 500,
});
aegis.alias(newUserId)

Merge two user identities.

aegis.alias('permanent_user_id');
aegis.reset()

Clear user identity on logout. Generates a new anonymous ID.

aegis.reset();
aegis.flush()

Force-send all queued events immediately.

await aegis.flush();

E-Commerce Tracking

Built-in helpers for standardized e-commerce events via aegis.ecommerce:

import aegis from '@active-reach/web-sdk';

// Product discovery
aegis.ecommerce.productViewed({
  product_id: 'SKU-123',
  name: 'Leather Jacket',
  price: 4999,
  currency: 'INR',
  category: 'Outerwear',
  brand: 'Acme',
  variant_id: 'black_xl',
  variant_label: 'Black XL',
});

aegis.ecommerce.productListViewed({
  list_name: 'New Arrivals',
  category: 'Outerwear',
  products: [{ product_id: 'SKU-123', name: 'Leather Jacket', price: 4999 }],
});

aegis.ecommerce.searchPerformed({ query: 'leather jacket', results_count: 12 });

// Cart
aegis.ecommerce.addToCart({
  product_id: 'SKU-123',
  name: 'Leather Jacket',
  price: 4999,
  quantity: 1,
});

aegis.ecommerce.removeFromCart({ product_id: 'SKU-123', name: 'Leather Jacket', price: 4999 });

aegis.ecommerce.cartViewed({
  cart_id: 'cart_456',
  value: 4999,
  products: [{ product_id: 'SKU-123', name: 'Leather Jacket', price: 4999, quantity: 1 }],
});

// Checkout
aegis.ecommerce.checkoutStarted({
  value: 4999,
  products: [{ product_id: 'SKU-123', name: 'Leather Jacket', price: 4999, quantity: 1 }],
  coupon: 'WELCOME10',
  shipping: 99,
  tax: 450,
});

aegis.ecommerce.checkoutStep(2, { payment_method: 'UPI' });

// Order
aegis.ecommerce.orderCompleted({
  order_id: 'ORD-789',
  value: 5548,
  revenue: 4999,
  shipping: 99,
  tax: 450,
  payment_method: 'UPI',
  products: [{ product_id: 'SKU-123', name: 'Leather Jacket', price: 4999, quantity: 1 }],
});

aegis.ecommerce.orderRefunded('ORD-789', 4999);

// Coupons
aegis.ecommerce.couponApplied({ coupon_code: 'WELCOME10', discount_value: 500, discount_type: 'fixed' });
aegis.ecommerce.couponRemoved({ coupon_code: 'WELCOME10' });

// Wishlist
aegis.ecommerce.wishlistItemAdded({
  product: { product_id: 'SKU-123', name: 'Leather Jacket', price: 4999 },
});

// Promotions
aegis.ecommerce.promotionViewed({ name: 'Summer Sale', promotion_id: 'promo_1', creative: 'banner_hero' });
aegis.ecommerce.promotionClicked({ name: 'Summer Sale', promotion_id: 'promo_1' });
All E-Commerce Methods
Method Event Name Description
productViewed(product) product_viewed User views a product page
productListViewed(list) product_list_viewed User views a category/collection
searchPerformed(search) search_performed User searches the catalog
addToCart(product) cart_item_added Item added to cart
removeFromCart(product) cart_item_removed Item removed from cart
cartViewed(cart) cart_viewed User views their cart
checkoutStarted(checkout) checkout_started Checkout flow begins
checkoutStep(step, options?) checkout_step Checkout step completed
orderCompleted(order) order_completed Purchase completed
orderRefunded(orderId, value?, products?) order_refunded Order refunded
couponApplied(coupon) coupon_applied Coupon/discount applied
couponRemoved(coupon) coupon_removed Coupon removed
wishlistItemAdded(wishlist) wishlist_item_added Item added to wishlist
promotionViewed(promo) promotion_viewed Promotion impression
promotionClicked(promo) promotion_clicked Promotion clicked

React Hooks

Import from @active-reach/web-sdk/react:

Hook Returns Description
useAegis() { aegis, isReady } Access SDK instance and readiness state
useTrackEvent() (name, props?) => void Memoized event tracking callback
usePageView(name?, props?, deps?) Track page views on mount/dependency change
useIdentifyUser() (userId, traits?) => void Memoized identify callback

Built-in support for GDPR/CCPA compliance.

// Set preferences
aegis.setConsent({ analytics: true, marketing: false, functional: true });

// Grant / deny
aegis.grantConsent();           // all categories
aegis.grantConsent('analytics'); // specific category

aegis.denyConsent();
aegis.denyConsent('marketing');

// Query
aegis.hasConsent('analytics');   // boolean
aegis.getConsentPreferences();   // full object

// Listen for changes
const unsubscribe = aegis.onConsentChange((prefs) => {
  console.log('Consent updated:', prefs);
});
Third-Party Integrations
// OneTrust
aegis.init('KEY', { enable_consent_mode: true, integrate_onetrust: true });

// Cookiebot
aegis.init('KEY', { enable_consent_mode: true, integrate_cookiebot: true });

// Google Consent Mode v2
aegis.init('KEY', { enable_consent_mode: true, integrate_google_consent_mode: true });

Web Push Notifications

Import from @active-reach/web-sdk/push:

import { AegisWebPush } from '@active-reach/web-sdk/push';

const push = new AegisWebPush({
  writeKey: 'YOUR_WRITE_KEY',
  apiHost: 'https://YOUR_CELL.activereach.ai',
  vapidPublicKey: 'YOUR_VAPID_PUBLIC_KEY',
  contactId: 'user_123',
  organizationId: 'org_456',
  serviceWorkerPath: '/aegis-sw.js',
});

await push.initialize();

Copy dist/aegis-sw.js to your public/ directory so the service worker is served at the root.


In-App Messaging & Widgets

Every in-app format — modals, banners, tooltips, full-screen takeovers, bottom sheets, and interactive widgets (spin-the-wheel, scratch cards, NPS/CSAT surveys, quizzes, countdown offers, star ratings, polls, multi-step forms) — is delivered through a single entry point: AegisMessageRuntime.

import { AegisMessageRuntime } from '@active-reach/web-sdk';

const runtime = new AegisMessageRuntime({
  writeKey: 'YOUR_WRITE_KEY',
  apiHost: 'https://YOUR_CELL.activereach.ai',
  contactId: 'user_123',     // optional — set once the visitor is known
  organizationId: 'org_456',
  propertyId: 'prop_789',    // the SDK install (website/app) this page is
});

await runtime.initialize();

Migrating from an older version? AegisInAppManager, AegisWidgetManager, and AegisPlacementManager are no longer part of the public API — AegisMessageRuntime is the one supported entry point and renders all formats. The standalone "placement" system has been removed; inline content is now delivered as embedded cards (see below).

Campaign content, audience, schedule, and frequency caps are configured server-side in the dashboard (In-App Personalization). The SDK evaluates client-side triggers (scroll depth, time on page, exit intent, inactivity, custom events) and renders the matching campaign automatically.

Drive triggers & identity from your app
runtime.track('added_to_cart');         // fire event-based display triggers
runtime.notifyConversion('purchase');   // suppress a campaign after it converts
await runtime.updateContactId('contact_42'); // re-evaluate once the visitor signs in
Placement — how a campaign reaches the customer

Each campaign picks one or more delivery modes in the dashboard's Placement tab. They are not mutually exclusive:

Delivery mode What it is What you do on your site
Pop up (overlay) A modal / banner / etc. the SDK renders over the page at runtime Nothing — runtime.initialize() shows it when the trigger matches
Embedded card The campaign renders inline, inside a slot you place on the page Add an empty <div data-aegis-slot="…"> where you want it
Standalone page The campaign gets its own tokenized URL (great for SMS / email / QR) Link to the URL shown in the dashboard
Embedded cards (inline placement)

Drop an empty element wherever you want the card to appear. Its data-aegis-slot value must equal the campaign's category (widget_category in the dashboard). On load, the SDK fills the first eligible campaign for that category:

<!-- Renders the active "promo" campaign here, inline in your page -->
<div data-aegis-slot="promo"></div>

No per-slot script and no manual registration — runtime.initialize() scans for every [data-aegis-slot] element and fills it. It re-scans on each SSE/poll refresh and skips slots it has already filled.

Cart state — one store, fed the CEP-standard way

Every cart-reactive surface — the free-delivery progress card, the standalone progress bar, cart-value targeting rules, and cart-recovery widgets — reads ONE cart store. You feed it the same way you'd feed WebEngage/CleverTap: by firing the ecommerce events you already fire. The SDK derives the live cart from them; no separate cart call.

// 1) Wire the ecommerce tracker into the cart store, once at boot:
runtime.bindEcommerce(aegis.ecommerce);

// 2) Fire ecommerce events as the shopper shops — the cart is derived from these:
aegis.ecommerce.addToCart({ product_id: 'p1', name: 'Cap', price: 499, quantity: 1 });
aegis.ecommerce.cartViewed({ value: 998, currency: 'INR', products: [/* … */] }); // authoritative snapshot

Platform installs need no event wiring — the plugin does it for you. Carts are detected and fed into the same store automatically:

Platform Detection method Setup
Shopify /cart.js poll + cart:updated (plugin) Install the Shopify app
WooCommerce aegis_cart + WC Store API on cart events (plugin) Install the WP plugin
Magento 2 localStorage['mage-cache-storage'] Install the extension
Custom / headless / mobile Fire aegis.ecommerce.* (above) runtime.bindEcommerce(...)

Escape hatch — a headless host that doesn't emit ecommerce events can push the cart directly; this writes the same one store:

runtime.setCartState({ total: 149.99, itemCount: 2, currency: 'INR' });

Plugin System

Extend the SDK with custom plugins:

import type { Plugin } from '@active-reach/web-sdk';

const myPlugin: Plugin = {
  name: 'my-plugin',
  version: '1.0.0',

  async init(config) { /* called on SDK init */ },

  async beforeEventCapture(event) {
    // Modify or enrich events before capture
    event.properties = { ...event.properties, enriched: true };
    return event;
  },

  async afterEventCapture(event) {
    // Post-capture logic (external forwarding, logging, etc.)
  },
};

aegis.use(myPlugin);

TypeScript Support

Full type definitions included. Extend for type-safe event tracking:

// types/aegis.d.ts
import '@active-reach/web-sdk';

declare module '@active-reach/web-sdk' {
  interface TrackEventProperties {
    'Purchase Completed': {
      order_id: string;
      revenue: number;
      currency: string;
    };
    'Product Viewed': {
      product_id: string;
      product_name: string;
      price: number;
    };
  }
}

Cookies & Storage

Name Type Purpose Duration
aegis_anon_id Cookie Anonymous user identifier 365 days
aegis_user_id Cookie Identified user ID 365 days
aegis_session_id Cookie Current session ID Session
aegis_session_time Cookie Last activity timestamp Session
aegis_consent Cookie Consent preferences 365 days
aegis_offline_queue localStorage Offline event queue Persistent
aegis_active_cell localStorage Active regional cell 7 days

All cookies: SameSite=Lax, Secure (HTTPS only), domain-scoped (optional).


Content Security Policy (CSP)

If your site uses a Content Security Policy, add these directives:

script-src: 'self' https://cdn.activereach.ai;
connect-src: 'self' https://*.activereach.ai;
style-src: 'self' 'unsafe-inline';
img-src: 'self' https://*.activereach.ai data:;

If using DOMPurify via CDN, also add:

script-src: https://cdnjs.cloudflare.com;

Common error when CSP is missing: Refused to connect to 'https://...activereach.ai' — add the domain to connect-src.


Security

  • Write Key: Publishable client-side identifier. Cannot read data or modify server state. Safe to embed in source code.
  • HTML Sanitization: Uses DOMPurify when available with a strict allowlist. Falls back to text-only rendering.
  • URL Validation: All URLs validated — javascript: and data: protocols blocked.
  • Consent: Events are dropped (not queued) when consent is denied and wait_for_consent is enabled.
  • Transport: All API calls use HTTPS with bearer token authentication.
What NOT to track

Never pass sensitive data as event properties:

// Never do this
aegis.track('Login', { password: '...' });
aegis.identify('user_123', { ssn: '...', credit_card: '...' });

The SDK does not filter or redact properties. You are responsible for ensuring no PII beyond what you intend to collect is included in event payloads.


Debugging

aegis.debug(true);

// Or via init
aegis.init('KEY', { debug: true });

Console output:

[Aegis] Initializing SDK...
[Aegis] Event queued: track { button_name: 'Sign Up' }
[Aegis] Flushing 5 events
[Aegis] Batch sent successfully

Subpath Exports

Import Path Description
@active-reach/web-sdk Core SDK (track, identify, page, group, alias)
@active-reach/web-sdk/react React Provider + hooks
@active-reach/web-sdk/push Web Push notification manager
@active-reach/web-sdk/cdn IIFE bundle for <script> tag (window.aegis)
@active-reach/web-sdk/snippet Minified async loader snippet
@active-reach/web-sdk/service-worker Push notification service worker

Browser Support

Chrome 80+, Firefox 78+, Safari 14+, Edge 80+.


License

MIT