@nivo-sdk/analytics
v0.1.0
Published
Observe-only browser analytics for Nivo video. Attach it to any `<video>` element and it reports the viewer lifecycle (impressions, view start, heartbeats, seeks, errors, watch-time, segment engagement, quality changes) to the Nivo analytics ingest servic
Downloads
63
Readme
@nivo-sdk/analytics
Observe-only browser analytics for Nivo video. Attach it to any <video>
element and it reports the viewer lifecycle (impressions, view start,
heartbeats, seeks, errors, watch-time, segment engagement, quality changes) to
the Nivo analytics ingest service.
Observe-only contract: the SDK never manipulates playback. It only reads
currentTime / duration and listens for media events — no play(),
pause(), seek(), or property mutations, ever. Every listener and network
send is wrapped in try/catch and fails silently, so it can never throw into the
host page or affect playback.
If you render your player with React, prefer
@nivo-sdk/player-react — it wires this monitor up for you.
Use this package directly for non-React players or custom integrations.
Install
bun add @nivo-sdk/analytics
# or: npm install @nivo-sdk/analyticsVanilla usage — monitor(el, opts)
import { monitor } from '@nivo-sdk/analytics'
const video = document.querySelector('video')
const handle = monitor(video, {
writeKey: 'nvo_pub_xxx',
videoId: 'kT9aFp2xQ7mB',
})
// later, when tearing the player down:
handle.destroy()monitor takes the media element and an options object, and returns a handle:
| Option | Type | Default | Description |
|---|---|---|---|
| writeKey | string | — (required) | Publishable analytics key. |
| videoId | string | — (required) | Nivo video id. |
| ingestUrl | string | https://analytics.nivo.video | Ingest origin; the SDK appends /v1/collect. |
| metadata | Record<string, unknown> | — | Custom key/values attached to every beacon. |
| player / playerVersion | string | auto-detected | Override the reported player identity. |
| heartbeatSeconds | number | SDK default | Heartbeat cadence while playing. |
| viewerId | string | persistent local id | Override the viewer identity. |
Returned MonitorHandle:
| Method | Description |
|---|---|
| destroy() | Detach listeners and end the view (emits view_end or impression). |
| flush() | Drain buffered events immediately. |
| reportQuality({ height?, bitrate? }) | Emit a quality_change event (call from your player's quality-switch hook). |
The view starts on the first play event, not at monitor() call time.
Heartbeats fire only while playing; a video that loads but never plays emits a
single impression. See the package AGENTS.md for the full lifecycle.
React usage — useNivoAnalytics
The ./react entry provides a hook that attaches a monitor to a video-element
ref and tears it down on unmount / videoId change:
'use client'
import { useRef } from 'react'
import { useNivoAnalytics } from '@nivo-sdk/analytics/react'
export function Player({ videoId }: { videoId: string }) {
const ref = useRef<HTMLVideoElement>(null)
const analytics = useNivoAnalytics({
ref,
videoId,
writeKey: 'nvo_pub_xxx',
})
// forward quality switches from your player:
// analytics?.reportQuality({ height: 720, bitrate: 2_500_000 })
return <video ref={ref} src="https://stream.nivo.video/v1/v/kT9aFp2xQ7mB" />
}useNivoAnalytics({ ref, videoId, writeKey?, metadata?, ingestUrl? }) returns
{ reportQuality } | undefined (undefined until attached — e.g. no writeKey
or the ref is null). It re-attaches only when videoId or writeKey changes.
CDN <script> usage
The IIFE build exposes globalThis.NivoBeacon, so you can attach analytics
without a bundler:
<video id="v" src="https://stream.nivo.video/v1/v/kT9aFp2xQ7mB"></video>
<script src="https://cdn.nivo.video/beacon/v1/beacon.js"></script>
<script>
NivoBeacon.monitor(document.getElementById('v'), {
writeKey: 'nvo_pub_xxx',
videoId: 'kT9aFp2xQ7mB',
})
</script>NivoBeacon exposes the same monitor(el, opts) API as the module import. Pin a
specific version instead of the mutable v1 alias by using the versioned path,
e.g. https://cdn.nivo.video/beacon/0.1.0/beacon.js.
Environments
Defaults target Nivo production (analytics.nivo.video). For staging or
self-host, set ingestUrl to the ingest origin — e.g.
ingestUrl: 'https://analytics.getomni.dev' posts to
https://analytics.getomni.dev/v1/collect.
