@rcigroup/horizon-analytics-sdk
v0.2.2
Published
Browser-focused analytics SDK for Horizon products.
Readme
@rcigroup/horizon-analytics-sdk
Browser-focused analytics SDK for Horizon products.
Installation
npm install @rcigroup/horizon-analytics-sdkExposed API
The package exposes these methods:
configureAnalyticsrecordEventrecordRichEventvalidateEventanalyticsTargets— common target/action constants (see below)
Configuration
Consumers only need to configure application metadata once:
import { configureAnalytics } from "@rcigroup/horizon-analytics-sdk";
configureAnalytics({
context: {
app: {
name: "Horizon Console",
version: "9.1.0",
},
},
});Event Contract
Every emitted payload uses schema 2.0.0 and is shaped as:
{
"schema": "2.0.0",
"context": {
"sdk": {
"name": "horizon-analytics-sdk",
"version": "0.1.0"
},
"app": {
"name": "Horizon Console",
"version": "9.1.0"
},
"device": {
"agent": "Mozilla/5.0 ...",
"os": "macOS",
"agent-raw": {
"brands": [{ "brand": "Chromium", "version": "136" }],
"mobile": false,
"platform": "macOS"
}
},
"user": {
"name": "Jake Brown",
"id": "user-42",
"email": "[email protected]",
"token": "SUPABASE_ACCESS_TOKEN"
},
"session": {
"id": "session-live-123"
}
},
"events": [
{
"id": "01977e8f-4d50-7cc8-9d54-7ce5f6d0e580",
"target": "checkout-button",
"action": "click",
"timestamp": "2026-01-01T10:00:00.000+00:00",
"location": {
"origin": "app.horizon.local",
"route": "/checkout"
},
"payload": {
"plan": "pro"
}
}
]
}Context Hydration
The SDK automatically populates:
context.sdk.nameashorizon-analytics-sdkcontext.sdk.versionfrom the package version injected by Vite at build/publish time via__SDK_VERSION__context.device.*from browser globals when availableevents[0].idwith a UUIDv7events[0].timestampwith the local timezone offsetevents[0].location.originandevents[0].location.route
recordRichEvent also hydrates context.user and context.session from Supabase user/session objects when available. If optional browser or Supabase fields are unavailable, the SDK emits null for those context values and falls back to "unknown" origin or "/" route in non-browser environments.
Origin Normalization
The SDK automatically strips the URL scheme from origin values during recording. For example, https://app.horizon.local is recorded as app.horizon.local. This happens transparently — callers do not need to change existing call sites.
Backend Delivery
recordEvent and recordRichEvent always send every valid event envelope to the analytics backend.
- Default backend endpoint:
https://ufptzleifvxclheanssz.supabase.co/functions/v1/vision-ingest-event
- If the backend returns a non-
200status, the SDK logs a warning toconsole.warn. - The SDK does not retry failed requests.
You can override the backend URL globally in your app:
import { setAnalyticsBackendUrl } from "@rcigroup/horizon-analytics-sdk";
setAnalyticsBackendUrl("https://analytics.example.com/events");If you do not set a URL, the default endpoint above is used.
Common Targets and Actions
analyticsTargets is a typed helper that provides common target/action name constants with full TypeScript autocomplete:
import { analyticsTargets, recordEvent } from "@rcigroup/horizon-analytics-sdk";
// Use a common target and action from the helper
recordEvent({
target: "authentication",
action: analyticsTargets.authentication.login,
});
recordEvent({
target: "page",
action: analyticsTargets.page.load,
});
recordEvent({
target: "form",
action: analyticsTargets.form["validation-fail"],
});Available targets and their actions:
| Target | Actions |
| ---------------- | ---------------------------------------------- |
| authentication | login, refresh, logout |
| authorization | deny, grant |
| page | load, redirect |
| file | upload, download |
| performance | slow, timeout |
| form | submit_success, submit_fail, validation-fail |
| configuration | update |
Consumers can also pass any arbitrary string for target and action — the helper is additive and does not constrain the API:
recordEvent({
target: "my-custom-widget",
action: "custom-interaction",
});Usage
import {
analyticsTargets,
configureAnalytics,
recordEvent,
recordRichEvent,
validateEvent,
} from "@rcigroup/horizon-analytics-sdk";
configureAnalytics({
context: {
app: {
name: "Horizon Console",
version: "9.1.0",
},
},
});
// Using the common targets/actions helper
const loginEvent = recordEvent({
target: "authentication",
action: analyticsTargets.authentication.login,
});
// Using custom target and action strings
const anonymousEvent = recordEvent({
target: "checkout-button",
action: "click",
payload: {
plan: "pro",
amount: 4999,
},
});
const authenticatedEvent = recordRichEvent({
target: "account-link",
action: "click",
payload: {
placement: "header",
},
user: {
id: "user-42",
email: "[email protected]",
user_metadata: {
full_name: "Jake Brown",
},
},
session: {
id: "session-live-123",
access_token: "SUPABASE_ACCESS_TOKEN",
},
});
for (const event of [loginEvent, anonymousEvent, authenticatedEvent]) {
const validation = validateEvent(event);
if (!validation.valid) {
console.error(validation.errors);
}
}Development
npm run build
npm run test
npm run typecheck
npm run lint