11metrics-pixel-react-native
v0.2.0
Published
Official 11metrics tracking SDK for React Native apps. Zero native dependencies — pure-JS SHA-256 hashing, a pluggable storage adapter for persistent anonymous IDs, and an optional React Navigation integration for automatic screen-view tracking.
Maintainers
Readme
11metrics-pixel-react-native
Official 11metrics tracking SDK for React Native apps. Talks to the same
POST /api/pixel endpoint the web pixel.js SDK uses — no backend changes
required to start receiving mobile events.
Zero native dependencies: hashing is pure-JS SHA-256 (no crypto.subtle,
no native crypto module to link), and identity persistence is a pluggable
storage adapter rather than a hard dependency on any specific storage
library. Works in Expo Go and bare React Native alike.
Install
npm install 11metrics-pixel-react-nativeUsage
// App.tsx
import AsyncStorage from '@react-native-async-storage/async-storage'; // recommended, not required
import { init, screenView, track, identify } from '11metrics-pixel-react-native';
init({
pixelId: 'YOUR_PIXEL_ID', // Settings → Pixel Setup in the 11metrics app
pixelUrl: 'https://app.11metrics.ai', // optional, this is the default
storage: AsyncStorage, // optional — omit to fall back to in-memory (resets each app restart)
});
// Manual screen tracking.
screenView('ProductDetail', { product_id: 'abc123' });
// Custom event.
track('button_press', { button: 'checkout' });
// After login. email/phone are hashed on-device before anything is sent.
identify({ email: '[email protected]', first_name: 'Marco' });Automatic screen tracking with React Navigation
import { NavigationContainer } from '@react-navigation/native';
import { trackNavigationStateChange } from '11metrics-pixel-react-native';
export default function App() {
return (
<NavigationContainer onStateChange={trackNavigationStateChange}>
{/* ... */}
</NavigationContainer>
);
}Not using React Navigation? Call screenView(name) yourself wherever your
navigation library exposes a focus/route-change event.
Why no native dependencies
- Hashing:
crypto.subtleisn't reliably available across React Native's JS engines (Hermes/JSC) and versions. Rather than require a native crypto module (native linking,pod install, Expo config plugins — friction most SDKs don't need to impose), this package ships its own pure-JS SHA-256 implementation, verified against known FIPS test vectors (seesmoke-test.mjs). - Storage: there's no browser-
localStorageequivalent built into React Native's JS runtime — every persistence option (AsyncStorage, MMKV, SecureStore) is a native module. Rather than pick one and force it on every consumer,init({ storage })accepts anything with agetItem/setItemshape.@react-native-async-storage/async-storageis the recommended default (it's already in most React Native apps), but MMKV or your own adapter both work identically. - React Navigation:
trackNavigationStateChangeacceptsstate: unknownrather than importing@react-navigation/native's types, so this package has zero dependency on it — apps using a different navigation library (or none) simply don't call that function.
API
init(config: { pixelId, pixelUrl?, storage?, gpc?, priorBlocking?, consent? })screenView(screenName, meta?)— sent asevent: "pageview", same event type web uses, so mobile screen views land in the same reports as web pageviews with no extra setup.track(name, meta?)— custom event.identify(data)—{ email?, phone?, first_name?, last_name? }.setConsent(granted: boolean)— record the visitor's consent decision from your app's consent screen (flushes buffered events + starts persisting the device id when granted; stops sending + drops the buffer when withdrawn).getAnonymousId()— the persisted per-device anonymous id.trackNavigationStateChange(state)— wire into React Navigation'sonStateChangefor automatic screen tracking.
Privacy: GPC & prior-blocking (parity with the web pixel)
RN has no cookies or navigator.globalPrivacyControl, so the equivalents are
config + storage:
- GPC —
init({ gpc: true })when your app should honour a universal opt-out (e.g. an OS/app "opt out of tracking" toggle). Analytics are suppressed, the device id is never persisted, and onegpc_optoutbeacon is sent so the server records the withdrawal in the consent ledger. - Prior-blocking —
init({ priorBlocking: 'geo' | 'strict' }). Events are buffered until a consent decision resolves, then replayed exactly once (the webq()defer/replay).geoasks/api/pixel/consent-contextand holds only for visitors who require prior consent;strictalways holds untilsetConsent(true). The persistent device id is written to storage only once analytics is allowed. - Default (
priorBlocking: 'off', nogpc) — unchanged: events send immediately. Drive consent yourself withsetConsent()/init({ consent: boolean }).
Local development
npm install
npm run build
npm test # runs the build, then sha256 + payload smoke testsPublishing
npm run build
npm test
npm login # once, with your npm account
npm publish # from this directoryBump version in package.json first if this isn't the first release.
