JavaScript SDK (browser and Node.js)
Install @iforevents/browser or @iforevents/node, identify users, track events and add adapters
The JavaScript family shares one core (@iforevents/core) and mirrors the Flutter package: a facade, pluggable integrations, and a first-party API integration that batches, retries and keeps an offline queue. The public project key is the only credential; there is no project secret in any SDK.
| Package | For |
|---|---|
@iforevents/browser | web apps and script tags (auto page views, localStorage queue, beacon flush) |
@iforevents/node | Node.js 18+ servers and workers (drains on exit) |
@iforevents/react, @iforevents/next, @iforevents/react-native | see React, Next.js and React Native |
@iforevents/mixpanel, @iforevents/amplitude, @iforevents/segment, @iforevents/posthog, @iforevents/ga4 | adapters: every call fans out to the vendor too |
Browser
npm install @iforevents/browserimport { createBrowserIforevents } from "@iforevents/browser";
const analytics = createBrowserIforevents("pk_...", { autoTrack: true });
await analytics.identify("user_123", { email: "[email protected]", plan: "pro" });
await analytics.track("signup_completed", { plan: "pro" });
await analytics.page("/pricing");
await analytics.reset(); // logoutWithout a bundler, the web snippet loads the same code from a script tag.
Node.js
npm install @iforevents/nodeimport { createIforevents } from "@iforevents/node";
const { iforevents, shutdown } = await createIforevents({ projectKey: process.env.IFOREVENTS_PROJECT_KEY! });
await iforevents.identify("user_123", { email: "[email protected]" });
await iforevents.track("invoice_paid", { amount: 120, currency: "USD" });
process.on("SIGTERM", () => shutdown().finally(() => process.exit(0)));Identity
Every request carries X-User-Id: a generated anon_... id the SDK keeps per visitor, replaced by your own id on identify. A user exists by its events alone; identify adds a profile with name, e-mail and traits. reset() starts a fresh anonymous id. Identify traits go to every integration once and are not copied into later events (each backend keeps them on the profile); nested objects are flattened with _.
Adapters
import { MixpanelIntegration } from "@iforevents/mixpanel/browser";
import { GA4Integration } from "@iforevents/ga4";
createBrowserIforevents("pk_...", {
integrations: [new MixpanelIntegration({ token: "..." }), new GA4Integration({ measurementId: "G-..." })],
});One failing adapter never affects the others: every call returns an IntegrationResult per integration.
Options
| Option | Default | Meaning |
|---|---|---|
baseUrl | https://api.iforevents.com | self-hosted installs pass their own origin |
batchSize | 20 | events per request; 1 sends immediately; max 500 |
flushInterval | 10000 ms | how long a partial batch waits |
maxRetries / retryDelay | 3 / 1000 ms | transient failures retry; Retry-After is honored |
persistQueue | browser true, node false | unsent events survive a reload |
onQuotaExceeded, onError | – | typed errors: IForeventsAuthError, IForeventsQuotaExceededError, IForeventsRateLimitedError |
Source: iforevents-sdks/js.