@gumlet/insights-react-native
v2.0.0
Published
React Native SDK to track video playback metrics using Gumlet Insights
Readme
@gumlet/insights-react-native
React Native SDK for Gumlet Insights. Wraps react-native-video (v5+) and emits the same analytics events as the web SDK via @gumlet/insights-js-core ≥ 3.0.2.
Requirements
| Package | Version |
|---------|---------|
| react | >=17 |
| react-native | >=0.68 |
| react-native-video | >=5.2.0 (v6+ recommended) |
| @react-native-async-storage/async-storage | >=1.17 |
| react-native-device-info | >=8 |
| react-native-uuid | >=2 |
| @gumlet/insights-js-core | ^3.0.2 |
Install
npm install @gumlet/insights-react-native @gumlet/insights-js-core
npm install react-native-video @react-native-async-storage/async-storage react-native-device-info react-native-uuidreact-native-url-polyfill is bundled as a dependency (required for ingest fetch).
Usage
import Video from 'react-native-video';
import withGumletInsights from '@gumlet/insights-react-native';
const TrackedVideo = withGumletInsights(Video);
export function Player() {
return (
<TrackedVideo
config={{
workspace_id: 'YOUR_WORKSPACE_ID', // required — Gumlet video-source Mongo _id
screen_name: 'Home',
screen_type: 'feed',
debug: __DEV__, // optional — logs /license and beacon debug via console.warn
}}
source={{ uri: 'https://example.com/video.m3u8' }}
paused={false}
muted={false}
style={{ width: '100%', height: 240 }}
/>
);
}The HOC always renders the wrapped Video immediately (no blank wait while session/user ids resolve in the background).
Config
| Key | Required | Description |
|-----|----------|-------------|
| workspace_id | Yes | Gumlet video-source id; gates GET /license |
| property_id | No | Optional legacy property id |
| screen_name | No | Maps to page_url / meta_page_url when page_url is unset |
| screen_type | No | Page type metadata (meta_page_type) |
| debug | No | Verbose license + beacon logging in core |
| test | No | Random UUIDs for user/session (skips durable identity) |
| customData1…10, user/video/player fields | No | Same as core AnalyticsConfig — see core README |
RN-only keys (screen_name, screen_type, captureDeviceName, player_integration_version) are stripped before passing config to core; device/player envelopes are built automatically.
Session & identity
| Storage key | Purpose |
|-------------|---------|
| gumlet_session_id | Durable session UUID (30-minute sliding window) |
| gumlet_session_expiry | Session TTL timestamp |
| gumlet_user_id | Durable user id (DeviceInfo unique id, persisted) |
Session HTTP (event_family=session) is sent only when AsyncStorage has no valid session id (first install, expiry, or after clearing storage). Reopening the app within 30 minutes reuses the id and does not resend session.
Playback activity extends session expiry via bumpSessionExpiry() on each analytics event.
To test a fresh session beacon in dev, clear storage before the tracked player mounts:
import { clearIdentityForTests } from '@gumlet/insights-react-native';
await clearIdentityForTests(); // dev/test helper onlyLoad vs session beacons
On each playback load you will see normal playback events (event_setup, event_player_ready, event_playback_ready, …) and optionally player_init (v1). Those are not session creation.
Look for session specifically:
- v2:
…/v2?event_family=session&… - v1: root ingest URL with
session_id=and no playbackevent=name
Advanced exports
import {
withGumletInsights,
ReactNativeVideoAdapter,
resolveSessionIdentity,
resolveUserId,
collectDeviceAndPlayerData,
clearIdentityForTests,
} from '@gumlet/insights-react-native';Use ReactNativeVideoAdapter.getPlayerIdentity() when wiring a custom player later.
Troubleshooting
| Symptom | Likely cause |
|---------|----------------|
| No beacons at all | /license denied — check workspace_id, Metro for [GumletInsights] Analytics disabled |
| orientation: undetected | Old core build — need @gumlet/insights-js-core ≥ 3.0.2 with RN orientation support |
| Session on every load | Old SDK, or HOC remounted with key={…} on the video — upgrade; avoid remounting per load |
| Spurious play/rebuffer on load | Old SDK — PLAY must come from onPlaybackStateChanged, not progress ticks |
| LoadBundleFromServerError | Old core — state machine must be statically imported (core ≥ 3.0.2) |
After upgrading linked packages locally, restart Metro with cache reset:
npx react-native start --reset-cacheMigration from 1.x
- Upgrade to
@gumlet/insights-react-native@2and@gumlet/insights-js-core@^3.0.2. - Pass
workspace_idinconfig(Mongo video-source id). - Default export is still an HOC:
withGumletInsights(Video). - The player always mounts immediately (no blank
<></>while session/user ids resolve).
Development
npm install
npm run typecheck
npm test
npm run buildLocal development against an unpublished core checkout:
"@gumlet/insights-js-core": "file:../insights-embed"Run npm run build:release in insights-embed after core changes, then reinstall in this package.
Release
Order: publish core first, then this package.
- Ensure
@gumlet/[email protected]is on npm. - Set dependency to
"@gumlet/insights-js-core": "^x.y.z"(notfile:../insights-embed). - Move
[Unreleased]→ version block inCHANGELOG.md. - Bump version and push tag:
npm version patch # or minor / major
git push origin main --follow-tagsCI (.github/workflows/main.yml) runs typecheck, tests, build, then npm publish --access public on tag push. Requires NPM_TOKEN in GitHub secrets.
Production app
npm install @gumlet/insights-react-native@latest @gumlet/insights-js-core@^3.0.2Ship through your normal iOS / Android release pipeline (EAS, TestFlight, Play Console, etc.).
Architecture
react-native-video callbacks
→ withGumletInsights HOC
resolveSessionIdentity / resolveUserId (AsyncStorage)
collectDeviceAndPlayerData (OS, display, orientation, player identity)
getOrCreateSharedAnalytics() ← one gumlet.insights() per JS runtime
→ ReactNativeVideoAdapter
→ GumletStateMachine (@gumlet/insights-js-core)
→ GET /license → session / session_event beacons (v1 + v2 mirror)Device metadata (meta_operating_system, orientation, display size, etc.) is attached to every event via core SampleBuilder. Orientation updates on Dimensions change.
License
MIT © Gumlet Pte. Ltd.
