@juanedev/analytics-core
v0.1.2
Published
Framework-agnostic core for Web Analytics. Written in TypeScript and usable from any app (React, Vue, Svelte, vanilla JS).
Readme
@juanedev/analytics-core
Framework-agnostic core for Web Analytics. Written in TypeScript and usable from any app (React, Vue, Svelte, vanilla JS).
- ESM + CJS
- No framework dependencies
- HTTP client + WebSocket (Socket.IO)
Installation
npm install @juanedev/analytics-core
# o
yarn add @juanedev/analytics-core
# o
pnpm add @juanedev/analytics-coreRequirements for the default backend:
- API HTTP (e.g.
http://localhost:4000) with endpoints/track/pageviewand/track/event. - Socket.IO Server (e.g.
ws://localhost:4000).
Quick usage
import {
initSession,
buildPageviewPayload,
buildEventPayload,
trackPageview,
trackEvent,
connectWebSocket,
disconnectWebSocket,
} from '@juanedev/analytics-core';
const apiUrl = 'http://localhost:4000';
const wsUrl = 'http://localhost:4000';
const websiteId = 'YOUR_WEBSITE_ID';
// 1) Create/recover userId, create sessionId and open WebSocket (with heartbeat)
const { userId, sessionId } = await initSession(websiteId, apiUrl, wsUrl);
// 2) Send pageview
await trackPageview(
apiUrl,
buildPageviewPayload(websiteId, window.location.href, sessionId, userId)
);
// 3) Send custom event
await trackEvent(
apiUrl,
buildEventPayload(websiteId, 'signup', { plan: 'pro' }, sessionId, userId)
);
// 4) Close WebSocket when you want to end the session (optional)
disconnectWebSocket();Suggestion for SPAs: send trackPageview on each client navigation.
API
Session and WebSocket
initSession(websiteId: string, apiUrl: string, wsUrl: string) => Promise<{ userId, sessionId }>- Generates
userId(persisted inlocalStorageif exists) andsessionId(UUID). - Opens WebSocket and emits
session:start. Activates heartbeat (session:ping).
- Generates
connectWebSocket(wsUrl: string, sessionData, heartbeatSeconds = 15)- Connects Socket.IO manually if you don't use
initSession.
- Connects Socket.IO manually if you don't use
disconnectWebSocket()- Emits
session:endand closes the WebSocket connection.
- Emits
Related types:
SessionData = { websiteId, apiUrl, wsUrl, userId, sessionId }
Tracking HTTP
trackPageview(apiUrl: string, payload: PageviewPayload)trackEvent(apiUrl: string, payload: EventPayload)
Helpers to build standard payloads:
buildPageviewPayload(websiteId, url, sessionId, userId)buildEventPayload(websiteId, eventName, properties, sessionId, userId)
Payload types:
type PageviewPayload = {
websiteId: string;
userId: string;
sessionId: string;
url: string;
referrer?: string;
userAgent?: string;
language?: string;
screen?: { width?: number; height?: number; colorDepth?: number; devicePixelRatio?: number };
utm?: { source?: string; medium?: string; campaign?: string; term?: string; content?: string };
timestamp?: string;
};
type EventPayload = {
websiteId: string;
userId: string;
sessionId: string;
eventName: string;
properties?: Record<string, unknown>;
url?: string;
referrer?: string;
utm?: { source?: string; medium?: string; campaign?: string; term?: string; content?: string };
timestamp?: string;
};Helpers
parseUtmsFromUrl(url?)→{ source, medium, campaign, term, content }getReferrer()getUserAgent()getLanguage()getScreen()→{ width, height, colorDepth, devicePixelRatio }isBrowser()
Framework integration
- React/Vue/Svelte: call
initSessionon client mount (e.g.useEffectin React). In SSR, invoke these functions only in the browser. - SPAs: listen to your router events to trigger
trackPageviewwhen the route changes.
Notes
- In environments without
window/document, the helpers returnundefined/empty values safely. fetchis required to send HTTP data (modern browsers or polyfill).
Build
The package is delivered compiled to:
- ESM:
dist/index.esm.js - CJS:
dist/index.cjs.js - Types:
dist/index.d.ts
License
MIT
