@yourownmetric/sdk
v0.1.3
Published
Your Own Metric — Privacy-first analytics SDK
Readme
@yourownmetric/sdk
Privacy-first, lightweight analytics SDK for web and Node.js applications.
~4 KB gzipped · Zero dependencies · Tree-shakeable · TypeScript-first
Don't have an account yet? Sign up free at Your Own Metrics →
Table of Contents
- Install
- Quick Start — JavaScript
- Quick Start — React
- Quick Start — Node.js
- CDN (No Build Step)
- HTML Data Attributes
- Environment Variables
- Integrating into an Existing Analytics Layer
- Auto-Captured Events
- Configuration Reference
- API Reference
- Embed Widget
- Privacy & Compliance
- Batching & Delivery
- Troubleshooting
- License
Install
npm install @yourownmetric/sdkGet your API key from the YOM Dashboard → API Keys.
Quick Start — JavaScript
import { YOM } from '@yourownmetric/sdk'
YOM.init({
apiKey: 'yom_pk_...', // From your YOM dashboard → API Keys
ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
autoCapture: {
pageviews: true, // SPA-aware — handles pushState + popstate
errors: true, // Uncaught errors & unhandled rejections
clicks: true, // Outbound links, downloads, data-yom-track elements
performance: true, // Core Web Vitals (LCP, CLS, INP, FCP, TTFB)
},
privacy: {
respectDNT: true, // Honor Do-Not-Track / Global Privacy Control
cookieless: false,
},
debug: false, // Set true during development
})
// That's it! Pageviews, errors, clicks, and Core Web Vitals are tracked automatically.Track Custom Events
// Fire-and-forget — events are batched automatically
YOM.track('signup_completed', { plan: 'pro', source: 'landing_page' })
// Track with revenue
YOM.track('purchase', { item: 'Premium Plan' }, { revenue: 49.99, currency: 'USD' })Identify Users
// Call after user login to link anonymous sessions to authenticated users
YOM.identify('user_abc123', {
name: 'Jane Doe',
email: '[email protected]',
plan: 'pro',
})Lifecycle
// Flush pending events (e.g. before navigation)
await YOM.flush()
// Tear down the SDK (cleanup listeners, flush, stop timers)
await YOM.destroy()Quick Start — React
import { YOMProvider, PageTracker } from '@yourownmetric/sdk/react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
const yomConfig = {
apiKey: 'yom_pk_...',
ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
autoCapture: {
pageviews: true,
errors: true,
clicks: true,
performance: true,
},
privacy: { respectDNT: true },
}
function App() {
return (
<YOMProvider config={yomConfig}>
<BrowserRouter>
<PageTracker />
<Routes>{/* your routes */}</Routes>
</BrowserRouter>
</YOMProvider>
)
}Using Hooks
import { useTrack, useIdentify } from '@yourownmetric/sdk/react'
function CheckoutButton() {
const track = useTrack()
const identify = useIdentify()
const handlePurchase = () => {
track('purchase', { item: 'Pro Plan' }, { revenue: 49.99, currency: 'USD' })
}
const handleLogin = user => {
identify(user.id, { name: user.name, email: user.email })
}
return <button onClick={handlePurchase}>Buy Now</button>
}React Hooks
| Hook | Description |
| -------------------- | -------------------------------------------- |
| useTrack() | Returns track(name, properties?, options?) |
| useIdentify() | Returns identify(userId, traits?) |
| usePageView(path?) | Tracks a pageview on mount / path change |
React Components
| Component | Description |
| ---------------------------- | -------------------------------------------------------- |
| <YOMProvider config={...}> | Context provider — initializes SDK, cleans up on unmount |
| <PageTracker /> | Drop-in — tracks pageviews on every route change |
Quick Start — Node.js
import { YOMNode } from '@yourownmetric/sdk/node'
const yom = new YOMNode({
apiKey: 'yom_pk_...',
ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
flushIntervalMs: 10_000, // Flush every 10s (default: 5s)
batchSize: 50, // Flush after 50 events (default: 20)
maxRetries: 3,
})
// Track server-side events
yom.track('api_request', {
endpoint: '/api/users',
method: 'GET',
statusCode: 200,
durationMs: 45,
})
// Identify users from your backend
yom.identify('user_abc123', {
name: 'Jane Doe',
email: '[email protected]',
})
// IMPORTANT: Flush before process exit
process.on('SIGTERM', async () => {
await yom.flush()
process.exit(0)
})Important:
- Always flush before exit — the Node client buffers events in memory.
- Create one
YOMNodeinstance per process and import it where needed.- Import from
@yourownmetric/sdk/node, not the default entry (which is browser-only).
CDN (No Build Step)
<!-- Add this before </head> — no build step required -->
<script type="module">
import { YOM } from 'https://cdn.yourownmetrics.aapastech.com/sdk/latest/index.js'
YOM.init({
apiKey: 'yom_pk_...',
ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
autoCapture: {
pageviews: true,
errors: true,
clicks: true,
performance: true,
},
})
</script>HTML Data Attributes
Track clicks without writing any JavaScript:
<!-- Auto-tracked by the clicks plugin -->
<button data-yom-track="cta_hero" data-yom-variant="blue">Get Started Free</button>
<!-- The click plugin reads data-yom-* attributes as event properties -->
<!-- Above will fire: { name: "cta_hero", variant: "blue", tagName: "button" } -->Environment Variables
Keep your API key out of source code:
# .env or .env.local
VITE_YOM_API_KEY=yom_pk_...
VITE_YOM_INGEST_URL=https://ingest.yourownmetrics.aapastech.comYOM.init({
apiKey: import.meta.env.VITE_YOM_API_KEY,
ingestUrl: import.meta.env.VITE_YOM_INGEST_URL,
// ...
})Integrating into an Existing Analytics Layer
If you already have a centralized dispatch for GA4, Facebook Pixel, Mixpanel, etc., add YOM alongside it with a single line:
import { YOM } from '@yourownmetric/sdk'
// 1. Initialize once at app boot
YOM.init({
apiKey: 'yom_pk_...',
ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
autoCapture: { pageviews: true, errors: true, clicks: true, performance: true },
})
// 2. In your existing analytics utility / dispatch hub:
export function sendAnalyticsEvent(name: string, params: Record<string, unknown>) {
// Existing services
ga4.sendEvent(name, params)
fbPixel.trackCustom(name, params)
// Add YOM — one extra line:
YOM.track(name, params)
}Auto-Captured Events
When autoCapture flags are enabled, the SDK tracks these events out-of-the-box — zero code required:
| Event | Flag | Description |
| ---------- | ------------------- | ------------------------------------------------------------------ |
| Pageviews | pageviews: true | Every navigation, SPA-aware (pushState + popstate) |
| Errors | errors: true | Uncaught errors & unhandled promise rejections |
| Clicks | clicks: true | Outbound links, file downloads, buttons, data-yom-track elements |
| Web Vitals | performance: true | LCP, CLS, FID/INP, FCP, TTFB — rated per Google thresholds |
| Sessions | always on | session_start / session_end with 30-min idle timeout |
| UTM Params | always on | Parsed from URL query string (utm_source, utm_medium, etc.) |
Configuration Reference
interface YOMConfig {
apiKey: string // Required — your public API key
ingestUrl?: string // Ingestion endpoint URL
autoCapture?: {
pageviews?: boolean // Default: false
errors?: boolean // Default: false
clicks?: boolean // Default: false
performance?: boolean // Default: false
}
privacy?: {
respectDNT?: boolean // Honor Do-Not-Track / GPC (default: false)
cookieless?: boolean // No localStorage anonymous IDs (default: false)
}
batchSize?: number // Events before flush (default: 20, max: 100)
flushIntervalMs?: number // Auto-flush interval (default: 5000)
maxRetries?: number // Transport retries (default: 3)
debug?: boolean // Console logging (default: false)
}API Reference
Browser (@yourownmetric/sdk)
| Method | Description |
| -------------------------------- | ------------------------------- |
| YOM.init(config) | Initialize the SDK (idempotent) |
| YOM.track(name, props?, opts?) | Track a custom event |
| YOM.page(path?, opts?) | Track a pageview |
| YOM.identify(userId, traits?) | Identify a user |
| YOM.flush() | Send all queued events |
| YOM.destroy() | Flush + cleanup listeners |
React (@yourownmetric/sdk/react)
| Export | Description |
| ---------------------------- | ------------------------------------------------ |
| <YOMProvider config={...}> | Context provider — init SDK, teardown on unmount |
| <PageTracker /> | Tracks pageviews on every route change |
| useTrack() | Returns track(name, properties?, options?) |
| useIdentify() | Returns identify(userId, traits?) |
| usePageView(path?) | Tracks pageview on mount / path change |
Node.js (@yourownmetric/sdk/node)
| Method | Description |
| ------------------------------- | ------------------------- |
| new YOMNode(config) | Create server-side client |
| yom.track(name, props?) | Track an event |
| yom.identify(userId, traits?) | Identify a user |
| yom.flush() | Send all queued events |
| yom.destroy() | Flush + stop timer |
Embed Widget
Display analytics data on any webpage using the <yom-dashboard> Web Component:
<script type="module" src="https://cdn.yourownmetrics.aapastech.com/embed/latest/index.js"></script>
<yom-dashboard
token="YOUR_EMBED_TOKEN"
dashboard-id="YOUR_DASHBOARD_ID"
api-url="https://api.yourownmetrics.aapastech.com/v1"
theme="auto"
></yom-dashboard>| Attribute | Required | Description |
| -------------- | -------- | ------------------------------------------------------------- |
| token | Yes | Embed token (create in Settings → API Keys with "read" scope) |
| dashboard-id | Yes | The ID of the dashboard to display |
| api-url | No | API base URL (defaults to production) |
| theme | No | "light", "dark", or "auto" (follows system preference) |
Privacy & Compliance
- Do-Not-Track / GPC: When
privacy.respectDNT: true, the SDK checksnavigator.doNotTrackandnavigator.globalPrivacyControl. If either is enabled, tracking is disabled entirely. - Cookieless mode: Set
privacy.cookieless: trueto disable localStorage-based anonymous IDs. Each page load gets a fresh random ID. - No PII by default: The SDK never captures form inputs, passwords, or personal data. User identification is opt-in via
YOM.identify().
Batching & Delivery
- Events are buffered in memory and sent in batches. Default: batch of 20 or every 5 seconds, whichever comes first.
- On page close (
visibilitychange → hidden), remaining events are sent vianavigator.sendBeacon()for reliable delivery. - Failed requests retry with exponential backoff (up to 3 retries). Permanently failed events (4xx except 429) are dropped.
Troubleshooting
Events not showing up in the dashboard?
Enable debug: true in your config. Check the browser console for [YOM] messages. Verify your API key is correct and not revoked.
CORS errors? The ingest endpoint accepts requests from any origin. If you're using a custom domain, make sure it matches your project's configured domain.
Events seem delayed?
Events are batched (default: 20 events or 5s). In development, reduce flushIntervalMs to 1000 for faster feedback.
Duplicate pageviews in SPA?
If you have autoCapture.pageviews enabled AND you're manually calling YOM.page(), you'll get duplicates. Choose one approach.
