EventFoundry tracking script for custom GA4 event tracking
npm install eventfoundry-trackerEmbedded 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.
- Installation
- Supported Destinations
- How It Works
- Features
- Configuration
- Development Mode
- Debugging Events
- Troubleshooting
- Editor Integration
- Architecture
- Browser Compatibility
- Development
- PostMessage API Reference
- License
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.
``html`
data-site-key="YOUR_SITE_KEY_HERE"
async>
Or use the latest version (auto-updates):
`html`
data-site-key="YOUR_SITE_KEY_HERE"
async>
`bash`
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.
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.
#### 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 reliabilityG-XXXXXXXXXX
- Configuration: Provide your GA4 Measurement ID (e.g., ) 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
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
When a user clicks a "Sign Up" button:
- GA4 receives: gtag('event', 'sign_up_click', {...params})fbq('trackCustom', 'sign_up_click', {...params})
- Meta Pixel receives:
- Future destinations: Automatically included when you enable them
Additional destinations coming soon:
- Google Ads conversion tracking
- TikTok Pixel
- LinkedIn Insight Tag
- Custom webhook destinations
EventFoundry Tracker operates in two distinct modes:
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 for efficiency
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. Multi-Destination Event Firing: When tracked elements are clicked:
- Generates auto-parameters (element text, URL, page title, etc.)
- Fires to all enabled destinations for that event using destination-specific adapters
- GA4 uses gtag('event', ...) with Beacon API transportfbq('trackCustom', ...)
- Meta Pixel uses
- Errors in one destination don't affect others
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: Uses a priority-based algorithm to create the most reliable selector
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
- 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 events 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
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)
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 helps you test EventFoundry tracking without sending events to any analytics destinations (GA4, Meta Pixel, etc.).
By default, the tracker automatically enables development mode when running on localhost:
`javascript`
// On localhost - dev mode is automatically enabled
// Events are logged to console but NOT sent to any destinations
You can override the auto-detection:
`html
data-site-key="YOUR_SITE_KEY_HERE"
data-dev-mode="true"
async>
data-site-key="YOUR_SITE_KEY_HERE"
data-dev-mode="false"
async>
`
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)
Development mode provides enhanced logging to help troubleshoot event tracking issues.
Debug logging automatically enables on localhost, or you can manually enable it:
`html`
data-site-key="YOUR_SITE_KEY_HERE"
data-dev-mode="true"
async>
When dev mode is enabled, the tracker logs helpful debugging information:
Destination Initialization:
``
EventFoundry: ā GA4 initialized (G-XXXXXXXXXX)
EventFoundry: ā Meta Pixel initialized (123456789)
Confirms each destination SDK was successfully loaded and configured.
Event Firing:
``
EventFoundry: Firing event button_click to 2 destinations
ā GA4: button_click {event_category: "EventFoundry", ...}
ā Meta Pixel: button_click {...}
Shows which destinations will receive the event and what parameters are being sent.
Non-Matching Clicks:
``
EventFoundry: Click on
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 destination error - gtag not available
GA4 SDK failed to load or was blocked by an ad blocker. Check browser console for script loading errors.
``
EventFoundry: Meta Pixel destination error - fbq not available
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: No valid event selectors found - tracking disabled!:has()
Critical: ALL event selectors are invalid. The tracker will not attach any click listeners. Common causes:
- Unsupported CSS pseudo-classes (e.g., in older browsers)
- Syntax errors in selectors
- Browser compatibility issues
If this error appears with cached data, the tracker will automatically clear the cache and refetch fresh 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, only firing first: ["Event 1", "Event 2"]
Multiple events matched the same click. Consider making your selectors more specific.
1. Enable dev mode and check console logs
2. Click the tracked element and look for:
- Firing event ... to 2 destinations ā Event is working, wait 24-48hrs for GA4 to show datamatched 0 events
- ā Your selector doesn't match the elementGA4 destination error
- ā 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:
javascript`
document.querySelector('.your-selector') // Should return the element
1. Enable dev mode and check console logs
2. Look for Meta Pixel initialized message - if missing, check:connect.facebook.net
- Meta Pixel ID is configured correctly in EventFoundry app
- Ad blockers aren't blocking
- 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)
- Check that the tracker loaded: look for ā EventFoundry tracker loaded in consoledata-site-key="..."
- Verify your site key is correct:
- Check browser console for errors during tracker initialization
- Ensure the element isn't inside an iframe (events only track in the same page)
- 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
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
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
- Wait up to 1 hour for cache to expire naturally
- Check for ETag validation in Network tab (should see 304 or 200 responses)
EventFoundry Tracker includes a sophisticated visual editor for defining events directly on your website.
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
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
The tracker uses a priority-based algorithm to generate reliable CSS selectors:
1. ID selectors (highest priority): #unique-element-id[data-track="value"]
2. Unique attributes: , [name="value"].class-name
3. Class-based selectors: , .multiple.classesdiv:nth-child(3)
4. Tag + nth-child: , with parent context for specificity
5. 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
Test your events before deploying:
- Preview mode logs events to the parent app instead of GA4
- See real-time feedback when clicking tracked elements
- Verify event parameters and tracking accuracy
- No impact on your actual GA4 data
EventFoundry Tracker is built with a modular, extensible architecture that separates concerns and makes adding new analytics platforms straightforward.
``
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
āāā destinations/
ā āāā destination-manager.js - Destination lifecycle and orchestration
ā āāā base-destination.js - Abstract base class for all destinations
ā āāā ga4-destination.js - Google Analytics 4 adapter
ā āāā meta-pixel-destination.js - Meta Pixel (Facebook) adapter
āāā utils/
āāā auto-params.js - Auto-parameter generation for events
- 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
- destination-manager.js: Destination lifecycle (initialization, event routing, error handling)
- base-destination.js: Abstract interface for destination adapters (SDK detection, injection, validation)
- ga4-destination.js: GA4-specific logic (gtag.js injection, event formatting, Beacon API)
- meta-pixel-destination.js: Meta Pixel logic (fbq.js injection, event formatting, PageView)
- auto-params.js: Automatic parameter extraction (element text, URL, page title, timestamp)
Each analytics platform is implemented as a destination adapter that extends BaseDestination:
`javascript
class GA4Destination extends BaseDestination {
// SDK detection and injection
async initialize(config) { ... }
// Event formatting and sending
sendEvent(eventName, params) { ... }
// Health checks
isAvailable() { ... }
}
`
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
- Format: IIFE (Immediately Invoked Function Expression)
- Target: ES2015 for broad browser compatibility
- Global: window.EventFoundry (for programmatic access if needed)
- Bundler: Rollup with Terser minification
- Optimizations: Template minification, console stripping, tree-shaking
- Size budget: <5 KB gzipped (enforced by CI/CD)
EventFoundry Tracker is built with ES2015+ JavaScript and supports all modern browsers:
- Chrome: 51+
- Firefox: 54+
- Safari: 10+
- Edge: 15+
- ES2015 syntax (arrow functions, const/let, template literals)
- localStorage APIfetch
- APInavigator.sendBeacon
- API (for reliable event delivery)postMessage
- API (for editor mode communication)
All these features are widely supported in browsers from 2016 onwards.
`bash`Install dependencies
npm install
`bashProduction build (outputs to dist/tracker.min.js)
npm run build
$3
The tracker uses Rollup for optimal tree-shaking and bundle optimization:
- Bundler: Rollup with Terser minification
- Template minification: CSS and HTML strings minified via custom plugin
- Console stripping: All
console.* statements removed from production builds
- Tree-shaking: Aggressive dead code elimination
- Sourcemaps: Generated in development mode for debugging
- Watch mode: Automatically rebuilds on file changes and outputs to sibling project
- Size budget: CI/CD enforces <5 KB gzipped limit$3
- 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$3
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$3
The tracker fetches configuration from the EventFoundry API. The response includes both event definitions and destination configurations:
`json
{
"destinations": {
"ga4": {
"enabled": true,
"measurementId": "G-XXXXXXXXXX"
},
"metaPixel": {
"enabled": true,
"pixelId": "123456789012345"
}
},
"events": [
{
"name": "Sign Up Click",
"selector": "button.signup",
"destinations": {
"ga4": {
"enabled": true,
"eventName": "sign_up_click",
"eventParams": {
"event_category": "User Actions"
}
},
"metaPixel": {
"enabled": true,
"eventName": "SignUpClick",
"eventParams": {}
}
}
}
]
}
`Key features:
- Global destination config: Contains credentials and enabled status for each destination
- Per-event destination control: Each event can enable/disable specific destinations
- Custom event names: Event names can differ per destination (e.g., snake_case for GA4, PascalCase for Meta)
- Custom parameters: Each destination can have different event parameters
- ETag caching: Response includes ETag header for efficient cache validation
PostMessage API Reference
When running in editor mode (inside EventFoundry app iframe), the tracker communicates with the parent window using the following PostMessage events:
$3
####
IFRAME_READY
Sent when the tracker initializes in editor mode.`javascript
{
type: 'IFRAME_READY'
}
`####
ELEMENT_SELECTED
Sent when a user selects an element in the visual editor.`javascript
{
type: 'ELEMENT_SELECTED',
selector: 'button.primary', // Generated CSS selector
tagName: 'BUTTON', // Element tag name
text: 'Click me', // Element text content
id: 'submit-btn', // Element ID (if present)
classes: ['primary', 'btn'], // Array of classes
attributes: { // All element attributes
type: 'submit',
'data-track': 'signup'
}
}
`####
EVENT_FIRED
Sent in preview mode when a tracked event is triggered. Includes destination-specific details.`javascript
{
type: 'EVENT_FIRED',
eventName: 'button_click',
destinations: [
{
name: 'GA4',
eventName: 'button_click',
params: { event_category: 'EventFoundry', ... }
},
{
name: 'Meta Pixel',
eventName: 'button_click',
params: { element_text: 'Click me', ... }
}
]
}
`$3
####
ENABLE_PREVIEW_MODE
Activates preview mode for testing events.`javascript
{
type: 'ENABLE_PREVIEW_MODE'
}
`####
DISABLE_PREVIEW_MODE
Deactivates preview mode and returns to normal editor mode.`javascript
{
type: 'DISABLE_PREVIEW_MODE'
}
``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.
MIT Ā© Kyle Logue