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

eventfoundry-tracker

v1.1.2

Published

EventFoundry tracking script for custom GA4 event tracking

Readme

EventFoundry Tracker

Embedded JavaScript tracking script for EventFoundry - enables multi-platform event tracking with a visual editor. Send events to Google Analytics 4, Meta Pixel, and other destinations from a single unified tracking implementation.

Table of Contents

Installation

Add the EventFoundry tracker script to your website's HTML. All destination configuration (GA4, Meta Pixel, etc.) is managed through the EventFoundry app - no credentials needed in the script tag.

Via jsDelivr CDN (Recommended)

<!-- Pinned to specific version (recommended for production) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tracker.min.js"
        data-site-key="YOUR_SITE_KEY_HERE"
        async></script>

Or use the latest version (auto-updates):

<!-- Latest version (auto-updates - use with caution) -->
<script src="https://cdn.jsdelivr.net/npm/eventfoundry-tracker@latest/dist/tracker.min.js"
        data-site-key="YOUR_SITE_KEY_HERE"
        async></script>

Via npm

npm install eventfoundry-tracker

That's it! Configure your tracking destinations (GA4, Meta Pixel, etc.) in the EventFoundry app, and events will automatically be sent to all enabled destinations.

Supported Destinations

EventFoundry Tracker uses a destination adapter architecture to support multiple analytics platforms from a single implementation. Each event you define can be sent to one or more destinations.

Currently Supported

Google Analytics 4 (GA4)

  • Auto-injection: EventFoundry automatically injects the GA4 SDK if not already present
  • Existing installations: If you already have GA4 installed, EventFoundry will detect and use it
  • Event delivery: Events sent via gtag('event', ...) with Beacon API transport for reliability
  • Configuration: Provide your GA4 Measurement ID (e.g., G-XXXXXXXXXX) in the EventFoundry app

Meta Pixel (Facebook Pixel)

  • Auto-injection: EventFoundry automatically injects the Meta Pixel SDK if not already present
  • Existing installations: If you already have Meta Pixel installed, EventFoundry will detect and use it
  • Event delivery: Custom events sent via fbq('trackCustom', ...)
  • Configuration: Provide your Meta Pixel ID in the EventFoundry app
  • Automatic PageView: EventFoundry sends an automatic PageView event on initialization

How Multi-Destination Works

  1. Configure once: Define your events in the EventFoundry app with descriptive names
  2. Enable destinations: Choose which destinations (GA4, Meta Pixel, etc.) should receive each event
  3. Unified tracking: The same event fires to all enabled destinations with the same parameters
  4. No code changes: Add or remove destinations without touching your website code

Example: Single Event, Multiple Destinations

When a user clicks a "Sign Up" button:

  • GA4 receives: gtag('event', 'sign_up_click', {...params})
  • Meta Pixel receives: fbq('trackCustom', 'sign_up_click', {...params})
  • Future destinations: Automatically included when you enable them

Roadmap

Additional destinations coming soon:

  • Google Ads conversion tracking
  • TikTok Pixel
  • LinkedIn Insight Tag
  • Custom webhook destinations

How It Works

EventFoundry Tracker operates in two distinct modes:

1. Tracking Mode (Production)

This is the default mode when the script is embedded on your website:

  1. Initialization: On page load, the tracker reads configuration from script attributes
  2. Configuration Fetch: Retrieves event definitions and destination configs from EventFoundry API using your site key
  3. Caching: Stores configuration in localStorage with ETag-based cache validation, stale-cache fallback on API/network failures, and safe-empty fallback when no usable cache is available
  4. Destination Initialization: Automatically initializes all enabled destination SDKs:
    • GA4: Injects gtag.js (or detects existing installation) and configures with your Measurement ID
    • Meta Pixel: Injects fbq.js (or detects existing installation) and configures with your Pixel ID
    • Each destination validates credentials and reports initialization status
  5. Click Tracking: Attaches click listeners to elements matching CSS selectors from your event definitions
  6. Event Resolution and Delivery: When tracked elements are clicked:
    • Generates auto-parameters (element text, URL, page title, etc.)
    • Resolves overlapping selector matches deterministically (highest specificity wins, then stable tie-breakers)
    • Fires to all enabled destinations for that event using destination-specific adapters
    • GA4 uses gtag('event', ...) with Beacon API transport
    • Meta Pixel uses fbq('trackCustom', ...)
    • Errors in one destination don't affect others

2. Editor Mode (EventFoundry App)

When loaded inside the EventFoundry application's iframe:

  1. Detection: Automatically detects iframe environment and initializes editor mode
  2. Visual Overlay: Displays an interactive overlay for selecting elements on your page
  3. Element Selection: Click any element to select it and generate an optimized CSS selector
  4. Selector Generation: Normalizes clicks to nearest interactive ancestor and uses a priority-based algorithm to create reliable selectors
  5. Communication: Sends element data back to the parent app via secure PostMessage
  6. Preview Testing: Allows testing events in preview mode with real-time logging showing all destinations

Features

  • Multi-Platform: Send events to multiple analytics platforms (GA4, Meta Pixel) from a single implementation
  • Lightweight: ~4.75 KB gzipped, <5 KB budget enforced by CI/CD
  • Zero dependencies: Pure vanilla JavaScript
  • Destination adapters: Extensible architecture makes adding new platforms simple
  • Auto-parameter generation: Automatically captures element context, page info, and event metadata
  • Fast: ETag-based caching with localStorage for efficient configuration updates
  • Non-blocking: Async loading and initialization won't slow down your site
  • Browser support: Chrome, Firefox, Safari, Edge (ES2015+)
  • Reliable delivery: Uses Beacon API (GA4) to ensure events complete even during navigation
  • Development mode: Auto-detects localhost and logs event routing without sending to destinations
  • Visual editor: Interactive element selection overlay for defining events
  • Smart selectors: Priority-based CSS selector generation algorithm
  • Secure communication: Origin validation for iframe PostMessage API
  • Per-event destination control: Enable/disable specific destinations for each event
  • Graceful degradation: If one destination fails, others continue to work

Configuration

Script Tag Attributes

The tracker script accepts the following data attributes:

Required

  • data-site-key: Your EventFoundry site key (obtained from your EventFoundry account)

Optional

  • data-dev-mode: Control development mode behavior
    • "true": Force development mode on (logs events, doesn't send to any destinations)
    • "false": Force production mode on
    • Not set: Auto-detects (dev mode on localhost, production mode elsewhere)
  • id="eventfoundry-tracker": Recommended when multiple tracker script tags may exist on the same page, for deterministic script config selection

Destination Configuration

All destination credentials (GA4 Measurement IDs, Meta Pixel IDs, etc.) are configured in the EventFoundry app, not in the script tag. This provides several benefits:

  • Security: No credentials exposed in client-side code
  • Flexibility: Update destinations without changing website code
  • Per-event control: Enable/disable destinations for individual events
  • Centralized management: Manage all tracking from one dashboard

To configure destinations:

  1. Log in to the EventFoundry app
  2. Navigate to your site settings
  3. Add your destination credentials (GA4 Measurement ID, Meta Pixel ID, etc.)
  4. Enable destinations globally and per-event as needed

Development Mode

Development mode helps you test EventFoundry tracking without sending events to any analytics destinations (GA4, Meta Pixel, etc.).

Auto-Detection

By default, the tracker automatically enables development mode when running on localhost:

// On localhost - dev mode is automatically enabled
// Events are logged to console but NOT sent to any destinations

Manual Control

You can override the auto-detection:

<!-- Force dev mode on production domain (for testing) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tracker.min.js"
        data-site-key="YOUR_SITE_KEY_HERE"
        data-dev-mode="true"
        async></script>

<!-- Force production mode on localhost (to test real destination events) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tracker.min.js"
        data-site-key="YOUR_SITE_KEY_HERE"
        data-dev-mode="false"
        async></script>

Behavior in Dev Mode

When development mode is active:

  • Events are logged to the browser console with full details for each destination
  • No events are sent to any analytics destinations (GA4, Meta Pixel, etc.)
  • A console message indicates dev mode is active
  • All tracking logic still runs (useful for testing selectors and event configuration)
  • Destination initialization still occurs (validates credentials and reports status)

Debugging Events

Development mode provides enhanced logging to help troubleshoot event tracking issues.

Enabling Debug Logging

Debug logging automatically enables on localhost, or you can manually enable it:

<!-- Enable debug logging on any domain -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tracker.min.js"
        data-site-key="YOUR_SITE_KEY_HERE"
        data-dev-mode="true"
        async></script>

Debug Console Messages

When dev mode is enabled, the tracker logs helpful debugging information:

Destination Initialization:

EventFoundry: Initializing 2 destination(s)
✓ GA4 initialized
✓ META_PIXEL initialized

Confirms each destination SDK was successfully loaded and configured.

Event Firing:

[DEV] Would fire to GA4: button_click {event_category: "EventFoundry", ...}
[DEV] Would fire to META_PIXEL: button_click {event_category: "EventFoundry", ...}
EventFoundry: Event fired to 2 destination(s): ["GA4", "META_PIXEL"]

Shows which destinations will receive the event and what parameters are being sent.

Non-Matching Clicks:

EventFoundry: Click on <button class="test"> matched 0 events

The clicked element doesn't match any of your event selectors. Check your event definitions to ensure the selector is correct.

Editor Mode:

EventFoundry: Click ignored (editor mode active, not in preview)

Clicks are ignored when the editor is active to prevent false events during element selection.

Critical Errors (Always Logged):

EventFoundry: GA4 not initialized - cannot fire event

GA4 SDK failed to load or was blocked by an ad blocker. Check browser console for script loading errors.

EventFoundry: Meta Pixel not initialized - cannot fire event

Meta Pixel SDK failed to load or was blocked. Check browser console for script loading errors.

EventFoundry: Invalid selector ".some[invalid:selector" - SyntaxError: ...

One of your event selectors is malformed. The tracker validates all selectors at initialization and logs warnings for each invalid selector.

🚨 EventFoundry: All event selectors invalid - possible cache corruption

Critical: ALL event selectors are invalid. The tracker will not attach any click listeners. Common causes:

  • Unsupported CSS pseudo-classes (e.g., :has() in older browsers)
  • Syntax errors in selectors
  • Browser compatibility issues

If this error appears with cached data during normal initialization, the tracker will clear cache and refetch definitions from the API.

EventFoundry: 2 of 10 selectors are invalid and will be skipped

Some (but not all) selectors are invalid. Tracking will continue for valid selectors, but invalid ones will be skipped. Check the console warnings above to see which selectors failed validation.

EventFoundry: Multiple events matched, firing highest priority: ["Event 2 [button.cta.primary]", "Event 1 [.cta]"]

Multiple events matched the same click. The tracker fires one event deterministically (highest selector priority). Consider making selectors non-overlapping for clarity.

Troubleshooting

Events aren't showing in GA4

  1. Enable dev mode and check console logs
  2. Click the tracked element and look for:
    • [DEV] Would fire to GA4: ... → Event is matching and routing correctly
    • matched 0 events → Your selector doesn't match the element
    • GA4 not initialized - cannot fire event → GA4 script is blocked or missing
  3. Verify GA4 is configured in EventFoundry app settings
  4. Check that GA4 Measurement ID is correct
  5. Use browser DevTools to verify your selector matches the element:
    document.querySelector('.your-selector') // Should return the element

Events aren't showing in Meta Pixel

  1. Enable dev mode and check console logs
  2. Look for ✓ META_PIXEL initialized message - if missing, check:
    • Meta Pixel ID is configured correctly in EventFoundry app
    • Ad blockers aren't blocking connect.facebook.net
    • Browser console for script loading errors
  3. Use Meta Pixel Helper browser extension to verify events are firing
  4. Check Meta Events Manager (events can take 20+ minutes to appear)

Click doesn't trigger any logs

  • Check that the tracker loaded: look for ✓ EventFoundry tracker loaded in console
  • Verify your site key is correct: data-site-key="..."
  • Check browser console for errors during tracker initialization
  • Ensure the element isn't inside an iframe (events only track in the same page)

Events fire in preview but not on live site

  • Check if destination scripts are being blocked by ad blockers
  • Enable dev mode on live site to see destination error messages
  • Verify destination credentials in EventFoundry app match your analytics accounts
  • Check browser console for Content Security Policy (CSP) violations

One destination works but another doesn't

This is expected behavior - destinations are independent:

  • If GA4 works but Meta Pixel doesn't, check Meta Pixel configuration
  • If Meta Pixel works but GA4 doesn't, check GA4 configuration
  • Each destination's errors are logged separately in dev mode

Cache issues

If events aren't updating after changes in the EventFoundry app:

  • Clear localStorage cache manually: localStorage.clear() in browser console
  • Use the "Reload Config" button in the EventFoundry app editor
  • Check for ETag validation in Network tab (should see 304 or 200 responses)
  • If the API is down, the tracker will use cached data when available (Definitions reload used cached payload fallback)
  • If no usable cache is available, reload falls back to safe-empty (Definitions reload fell back to safe-empty payload)

Editor Integration

EventFoundry Tracker includes a sophisticated visual editor for defining events directly on your website.

How Editor Mode Works

When your site is loaded inside the EventFoundry application:

  1. The tracker detects the iframe environment
  2. Sends an IFRAME_READY message to the parent app
  3. Activates the visual overlay system
  4. Waits for element selection requests from the parent app

Visual Element Selection

The editor overlay provides:

  • Click-to-select: Click any element to select it
  • Visual highlighting: Selected elements are highlighted in the overlay
  • Parent traversal: Navigate up the DOM tree to select parent elements
  • Selector preview: See the generated CSS selector in real-time

CSS Selector Generation

The tracker uses a priority-based algorithm to generate reliable CSS selectors:

  1. Interactive ancestor normalization: Resolves nested click targets to semantic clickable elements when possible
  2. ID selectors (highest priority): #unique-element-id
  3. Unique attributes: [data-track="value"], [name="value"]
  4. Class-based selectors: .class-name, .multiple.classes
  5. Tag + nth-child: div:nth-child(3), with parent context for specificity
  6. Fallback combinations: Combines multiple strategies for robustness

The algorithm ensures selectors are:

  • Specific enough to target the correct element
  • Resilient to minor page changes
  • Human-readable when possible

Preview Mode

Test your events before deploying:

  • Preview mode sends EVENT_FIRED messages to the parent app instead of firing destination adapters
  • See real-time feedback when clicking tracked elements
  • Verify event parameters and tracking accuracy
  • No impact on your destination data while preview is active

Architecture

EventFoundry Tracker is built with a modular, extensible architecture that separates concerns and makes adding new analytics platforms straightforward.

Source Structure

src/
├── index.js                  - Entry point, initialization, caching
├── tracker.js                - Event tracking engine, click listeners
├── editor-mode.js            - Editor mode detection and PostMessage
├── editor-overlay.js         - Visual overlay, element selection, selectors
├── params-generator.js       - Auto-parameter generation for events
└── adapters/
    ├── registry.js           - Adapter registry and lookup
    ├── base-adapter.js       - Abstract base class for all adapters
    ├── ga4-adapter.js        - Google Analytics 4 adapter
    └── meta-pixel-adapter.js - Meta Pixel adapter

Module Responsibilities

  • index.js: Configuration parsing, API communication, ETag-based caching
  • tracker.js: Click event handling, selector validation, event orchestration
  • editor-mode.js: Iframe detection, parent communication, mode switching
  • editor-overlay.js: DOM overlay rendering, element selection UI, CSS selector algorithm
  • registry.js: Adapter lifecycle lookup and destination routing
  • base-adapter.js: Abstract interface for destination adapters (SDK detection, injection, validation)
  • ga4-adapter.js: GA4-specific logic (gtag.js injection, event formatting, Beacon API)
  • meta-pixel-adapter.js: Meta Pixel logic (fbq.js injection, event formatting, PageView)
  • params-generator.js: Automatic parameter extraction (element text, URL, page title, timestamp)

Destination Adapter Pattern

Each analytics platform is implemented as a destination adapter that extends DestinationAdapter:

class GA4Adapter extends DestinationAdapter {
  // SDK detection and injection
  async initialize(config) { ... }

  // Event formatting and sending
  fireEvent(eventName, params) { ... }

  // Health checks
  isInitialized() { ... }
}

This pattern provides:

  • Isolation: Each destination operates independently
  • Extensibility: Adding new platforms requires only a new adapter class
  • Reliability: Failures in one destination don't affect others
  • Testability: Each adapter can be tested in isolation

Build Output

  • Format: IIFE (Immediately Invoked Function Expression)
  • Target: ES2015 for broad browser compatibility
  • Global bundle name: EventFoundry (IIFE name; no public runtime API surface)
  • Bundler: Rollup with Terser minification
  • Optimizations: Template minification, console stripping, tree-shaking
  • Size budget: <5 KB gzipped (enforced by CI/CD)

Browser Compatibility

EventFoundry Tracker is built with ES2015+ JavaScript and supports all modern browsers:

  • Chrome: 51+
  • Firefox: 54+
  • Safari: 10+
  • Edge: 15+

Required Browser Features

  • ES2015 syntax (arrow functions, const/let, template literals)
  • localStorage API
  • fetch API
  • navigator.sendBeacon API (for reliable event delivery)
  • postMessage API (for editor mode communication)

All these features are widely supported in browsers from 2016 onwards.

Development

Setup

# Install dependencies
npm install

Building

# Production build (outputs to dist/tracker.min.js)
npm run build

# Development watch mode (outputs to ../eventfoundry-app/frontend/public/test/tracker.min.js)
npm run dev

Build System

The tracker uses Rollup for optimal tree-shaking and bundle optimization:

  • Bundler: Rollup with Terser minification
  • Console stripping: console.log and console.warn removed from production builds (console.error preserved)
  • Tree-shaking: Aggressive dead code elimination
  • Sourcemaps: Inline in development mode and external in production
  • Watch mode: Automatically rebuilds on file changes and outputs to sibling project
  • Size budget: CI/CD enforces <5 KB gzipped limit

Build Configuration

  • Production builds: Optimize for size and performance, strip console logs
  • Development builds: Include sourcemaps, preserve console logs, faster iteration
  • Both modes: IIFE bundles targeting ES2015
  • Version injection: __VERSION__ replaced with package.json version at build time

Development Workflow

The dev build automatically outputs to ../eventfoundry-app/frontend/public/test/tracker.min.js for local integration testing. This allows you to:

  1. Make changes to the tracker
  2. See them immediately in the parent EventFoundry app (no publish needed)
  3. Test the full editor integration workflow locally

API Response Format

The tracker fetches configuration from the EventFoundry API. The response includes event definitions, destination configurations, and a version number:

{
  "destinationConfigs": [
    {
      "destination": "GA4",
      "enabled": true,
      "credentials": {
        "measurementId": "G-XXXXXXXXXX"
      }
    },
    {
      "destination": "META_PIXEL",
      "enabled": true,
      "credentials": {
        "pixelId": "123456789012345"
      }
    }
  ],
  "events": [
    {
      "eventKey": "sign_up_click",
      "eventLabel": "Sign Up Click",
      "selector": "button.signup",
      "destinations": {
        "GA4": { "enabled": true },
        "META_PIXEL": { "enabled": true }
      }
    }
  ],
  "version": 1
}

Key features:

  • Global destination config: Contains credentials and enabled status for each destination
  • Per-event destination control: Each event can enable/disable specific destinations
  • Canonical event keys: eventKey is used as the destination event name across adapters
  • Automatic params: Tracker-generated params are sent to each enabled destination adapter
  • ETag caching: Response includes ETag header for efficient cache validation
  • Stale-cache fallback: If the API is temporarily unavailable, cached definitions are used (with warnings)
  • Safe-empty fallback: If API and cache are both unavailable/unusable, tracker uses a no-op payload to avoid runtime failures

PostMessage API Reference

When running in editor mode (inside EventFoundry app iframe), the tracker communicates with the parent window using the following PostMessage events:

Messages Sent by Tracker (to Parent)

IFRAME_READY

Sent when the tracker initializes in editor mode.

{
  type: 'IFRAME_READY'
}

ELEMENT_SELECTED

Sent when a user selects an element in the visual editor.

{
  type: 'ELEMENT_SELECTED',
  element: {
    tagName: 'button',              // Lowercase tag name
    text: 'Click me',               // Truncated element text content
    id: 'submit-btn',               // Element ID (if present)
    className: 'primary btn',       // Space-separated class string
    selector: 'button.primary',     // Generated CSS selector
    page_path: '/pricing?plan=pro'  // Path + query + hash
  }
}

EVENT_FIRED

Sent in preview mode when a tracked event is triggered. Includes event metadata, params, and destination list.

{
  type: 'EVENT_FIRED',
  timestamp: 1739328000000,
  eventLabel: 'Button Click',
  eventKey: 'button_click',
  selector: 'button.primary',
  destinations: ['GA4', 'META_PIXEL'], // Enabled + initialized destinations
  params: { event_category: 'EventFoundry', ... },
  pagePath: '/pricing'
}

MATCH_COUNT_RESULT

Sent after the parent requests selector count via COUNT_MATCHES.

{
  type: 'MATCH_COUNT_RESULT',
  selector: 'button.primary',
  count: 3
}

Messages Received by Tracker (from Parent)

ENTER_EDIT_MODE

Activates editor overlay mode and enables element selection.

{
  type: 'ENTER_EDIT_MODE'
}

ENABLE_PREVIEW

Activates preview mode for testing events.

{
  type: 'ENABLE_PREVIEW'
}

DISABLE_PREVIEW

Deactivates preview mode and returns to normal editor mode.

{
  type: 'DISABLE_PREVIEW'
}

RELOAD_CONFIG

Triggers a full tracker config reload (definitions + destination re-initialization).

{
  type: 'RELOAD_CONFIG'
}

HIGHLIGHT_SELECTOR

Highlights all elements matching a selector in the overlay.

{
  type: 'HIGHLIGHT_SELECTOR',
  selector: 'button.primary'
}

COUNT_MATCHES

Requests the number of elements matching a selector.

{
  type: 'COUNT_MATCHES',
  selector: 'button.primary'
}

Security

All PostMessage communication includes origin validation to ensure messages are only accepted from authorized EventFoundry domains. This prevents malicious sites from interfering with the tracker's operation.

License

MIT © Kyle Logue