React Native Player (iOS + Android)
React Native Video is a popular player for video in React Native apps. Gumlet Insights v2 wraps it with a higher-order component (withGumletInsights) and sends the same playback analytics as the web SDK via @gumlet/insights-js-core.
Sample app
Prefer a working project? Clone gumlet/react-native-video-insights-sample — a React Native app that integrates react-native-video with Gumlet Insights. Set your workspace_id and stream URL, then run on iOS or Android.
Requirements
@gumlet/insights-react-native2.x@gumlet/insights-js-core4.0.1+- React ≥ 17, React Native ≥ 0.68
react-native-video≥ 5.2 (v6 recommended)
Step 1: Install packages
Install the Gumlet SDKs and peer dependencies (npm does not install peers automatically):
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-uuid
cd ios && pod install && cd ..
| Package | Why your app needs it |
|---|---|
react-native-video | Player wrapped by the SDK; callbacks drive play, pause, seek, rebuffer, and error events |
@react-native-async-storage/async-storage | Persists session and user ids across launches |
react-native-device-info | Device/OS metadata and durable user id |
react-native-uuid | Generates new session ids when storage is empty |
react-native-url-polyfill is bundled inside @gumlet/insights-react-native (ingest fetch). react-native-crypto is not required in v2.
React Native 0.73+ (optional Babel)
If Metro reports “Static class blocks are not enabled” when bundling core, add:
// babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['@babel/plugin-transform-class-static-block'],
};
Step 2: Import and wrap the player
Import withGumletInsights and your react-native-video component, then create a tracked player once (outside your screen component or in module scope):
import Video from 'react-native-video';
import withGumletInsights from '@gumlet/insights-react-native';
const TrackedVideo = withGumletInsights(Video);
You do not need a ref on the video for analytics in v2.
Step 3: Create the config object
All data is associated with a workspace ID from the Workspaces section. Pass it as workspace_id — this is the only required field. It gates the GET /license call; without a valid id, no events are sent.
Optional fields include screen name, custom user/video metadata, and debug logging. See custom data options for the full list (same shape as the web SDK).
const insightsConfig = {
workspace_id: 'YOUR_WORKSPACE_ID', // required
screen_name: 'Home',
screen_type: 'feed',
debug: __DEV__, // optional — verbose license/beacon logs in Metro
};
Do not set player_name — the SDK reports player_software: react-native-video and the installed player version automatically.
Step 4: Render the tracked player
Pass config, source, and paused from React state so PLAY/PAUSE beacons match real playback:
import React, { useMemo, useState } from 'react';
import { View } from 'react-native';
import Video from 'react-native-video';
import withGumletInsights from '@gumlet/insights-react-native';
const TrackedVideo = withGumletInsights(Video);
export function PlayerScreen() {
const [paused, setPaused] = useState(true);
const config = useMemo(
() => ({
workspace_id: 'YOUR_WORKSPACE_ID',
screen_name: 'Home',
screen_type: 'feed',
}),
[],
);
return (
<View>
<TrackedVideo
config={config}
source={{
uri: 'https://example.com/stream.m3u8',
}}
paused={paused}
muted={false}
resizeMode="contain"
style={{ width: '100%', aspectRatio: 16 / 9 }}
/>
</View>
);
}
Integration tips
- The player renders immediately — session and user ids resolve in the background (no blank placeholder).
- Avoid
key={source.uri}on the tracked player for every load; that remounts analytics. Updatesourcevia props instead. - Do not remount the whole screen with a new HOC instance on each navigation if you can keep one player tree alive.
Once integrated, verify GET /license?workspace_id=… in your network inspector, then press Play. Data should appear on your real-time dashboard.
Session vs playback events
| When | What is sent |
|---|---|
| First install (no stored session) | Session beacon once (event_family=session on v2 ingest) |
| App reopen within ~30 minutes | Same session id — no new session HTTP |
| Each video load / play | event_player_ready, event_playback_ready, play, pause, seek, rebuffer, etc. |
player_ready and player_init on load are not the same as session creation.
How to?
Add custom data
Pass first-party user, video, and player fields on the same config object. Full parameter list: custom data options.
const insightsConfig = {
workspace_id: 'YOUR_WORKSPACE_ID',
screen_name: 'Episode',
screen_type: 'detail',
userId: '123',
userName: 'Océane Bourgeois',
userEMail: 'oceane.bourgeois@example.com',
userPhone: '(840)-295-4133',
customVideoTitle: 'Pilot',
customVideoSeries: 'Season 1',
customVideoId: 'episode-1',
customData1: 'campaign-a',
customData2: 'variant-b',
};
You can also spread the core QA helper (every optional field prefilled):
import { fullCustomAnalyticsConfig } from '@gumlet/insights-js-core';
const insightsConfig = {
...fullCustomAnalyticsConfig,
workspace_id: 'YOUR_WORKSPACE_ID',
};
Enable debug logging
Set debug: true in config (or debug: __DEV__ in development). Logs appear in Metro via console.warn.
Reset session in development
import { clearIdentityForTests } from '@gumlet/insights-react-native';
await clearIdentityForTests(); // call before the tracked player mounts
Migrating from SDK 1.x
| 1.x | 2.x |
|---|---|
import gumletReactNativeVideo from '…' | import withGumletInsights from '…' |
gumletReactNativeVideo(Video) | withGumletInsights(Video) |
Config without workspace_id | workspace_id required |
react-native-crypto peer | Removed — not needed |
| Blank UI until ids resolved | Player always visible |
player_name in config | Omit — use automatic player_software |
Upgrade both packages together:
npm install @gumlet/insights-react-native@2 @gumlet/insights-js-core@^4.0.1
After upgrading, restart Metro with a clean cache:
npx react-native start --reset-cache
Troubleshooting
| Symptom | What to check |
|---|---|
| No beacons | Valid workspace_id; Metro for [GumletInsights] Analytics disabled |
| Session on every app open | Old SDK, or player remounted with key={…} on every load |
| Play events while paused | Pass paused from state; upgrade to v2 (PLAY from onPlaybackStateChanged) |
| False rebuffer on load | Upgrade to v2 (rebuffer from onBuffer, not progress stall timer) |
| Android emulator HLS errors | Use MP4 on emulators or test HLS on a physical device |

