DataPork

React Native configuration

Every option of DataPork.initialize, and how to describe your users and respect their consent.

Example

Only four options are required. A typical production setup adds the version of the build and the hosts of your own backend:

index.js
import { DataPork, LogLevel, PropagationFormat } from '@datapork/react-native';

DataPork.initialize({
  clientToken: '<client token>',
  applicationId: '<application ID>',
  env: 'prod',
  intakeUrl: 'https://<your DataPork intake>/v1/ingest',

  version: '2.3.0',
  buildSuffix: '482',
  sessionSampleRate: 50,
  slowJsTaskMs: 200,
  ownHosts: [
    'api.example.com',
    { match: 'legacy.example.com', propagation: [PropagationFormat.B3] },
  ],
  logLevel: __DEV__ ? LogLevel.DEBUG : undefined,
});

Options

Required

The console shows these values in Token and SDK, next to a ready-made snippet.

OptionTypeDefaultWhat it does
clientTokenstringnoneClient token of the application. It is sent with every upload to authenticate the app.
applicationIdstringnoneID of the application in DataPork.
envstringnoneEnvironment of this build, for example prod, staging or dev. Use it to filter in the console.
intakeUrlstringnoneFull URL of the intake of your DataPork server, ending in /v1/ingest. There is no default host: a missing or non-http(s) value rejects the initialization.

Which app and which build

OptionTypeDefaultWhat it does
servicestringbundle IDName of the service the events belong to. By default the Android application ID or the iOS bundle ID.
versionstringapp versionVersion of your app. By default the version name (Android) or the short version (iOS) of the installed build.
buildSuffixstringnoneAppended to the version with a dash, for example a build number or a CI run: 1.4.0 becomes 1.4.0-482.

Sampling

OptionTypeDefaultWhat it does
sessionSampleRatenumber100Percentage of sessions to track, from 0 to 100. The decision is made once per session.
traceSampleRatenumber100Percentage of requests to your own hosts that get trace headers, from 0 to 100. Change it later with DataPork.setTraceSampleRate().

What to capture

OptionTypeDefaultWhat it does
captureTapsbooleantrueRecord taps as actions.
captureRequestsbooleantrueRecord network requests (fetch and XMLHttpRequest) as resources.
captureErrorsbooleantrueRecord uncaught JavaScript errors and console.error calls as errors.
captureBackgroundbooleanfalseAlso record events that happen while the app is in the background.
slowJsTaskMsnumber0 (off)Record a long task whenever the JavaScript thread is blocked for longer than this many milliseconds.

Naming taps

See Naming taps below for the order in which the name of an action is chosen.

OptionTypeDefaultWhat it does
actionLabelPropstringnoneName of a prop to read the action name from, for example testID.
labelFromAccessibilitybooleantrueUse the accessibilityLabel of the tapped element (or a parent) as the action name. Set it to false to turn that off.

Tracing your own backend

OptionTypeDefaultWhat it does
ownHosts(string | OwnHost)[][]Hosts of your own backend. Requests to them (and their subdomains) get trace headers. A string uses W3C tracecontext; an object { match, propagation } picks the formats. Other hosts never get headers.

Upload, privacy and logging

OptionTypeDefaultWhat it does
uploadIntervalMsnumber10000Delay between upload attempts, in milliseconds.
consentConsentStateALLOWEDInitial tracking consent. See Consent below.
logLevelLogLeveloffPrints SDK messages to the console with the prefix [DataPork]: DEBUG, INFO, WARN or ERROR. Unset prints nothing.

Filters

Each one receives the event before it is stored. Return it (changed or not) to keep it, or null to drop it.

OptionTypeDefaultWhat it does
beforeSendError(event) => event | nullnoneCalled for every error event.
beforeSendResource(event) => event | nullnoneCalled for every resource (request) event.
beforeSendAction(event) => event | nullnoneCalled for every action event.

Naming taps

A tap is recorded as an action. Its name is the first of these that exists, looking from the tapped element up through its parents:

  1. the datapork-action-name prop,
  2. the prop named by the actionLabelProp option,
  3. the accessibilityLabel (also better for accessibility),
  4. the type of the element, for example RCTView for a Pressable.
Pay.tsx
<Pressable accessibilityLabel="Checkout" onPress={pay} />
<Pressable datapork-action-name="Checkout" onPress={pay} />

Tracing your backend

For requests to the hosts in ownHosts, the SDK adds trace headers, so a request in the console can be matched with what your backend saw. A host matches itself and its subdomains; when several entries match, the longest one wins. The formats are in PropagationFormat: TRACECONTEXT (the default), B3, B3MULTI and DATAPORK, which adds the SDK's own x-datapork-* headers. Invalid hostnames are ignored.

Users and accounts

Attach an identity to the sessions of a signed-in user. Call these whenever you learn the user, before or after initialize. Do not send what you do not need: the fields end up in the console.

auth.ts
// After login
DataPork.identifyUser({
  id: 'user-42',
  name: 'Ada Demo',
  email: 'ada@example.com',
  fields: { plan: 'pro' },
});
DataPork.identifyAccount({ id: 'acme', name: 'Acme Inc.' });

// Add a field later
DataPork.addUserFields({ onboarded: true });

// After logout
DataPork.forgetUser();
DataPork.forgetAccount();

Global attributes

Attributes added to every event from then on:

attributes.ts
DataPork.setGlobalAttribute('store', 'madrid');
DataPork.setGlobalAttributes({ experiment: 'new-checkout', locale: 'es' });
DataPork.clearGlobalAttributes(['experiment']);

The consent state decides what happens to events. ALLOWED (the default) sends them. UNDECIDED holds them in memory, up to 500 events, until you call updateConsent. DENIED drops them. When the consent becomes ALLOWED, the held events are sent.

consent.ts
import { DataPork, ConsentState } from '@datapork/react-native';

// Wait for the user's answer
DataPork.initialize({ /* ... */ consent: ConsentState.UNDECIDED });

// Later, from your consent screen
DataPork.updateConsent(ConsentState.ALLOWED); // or ConsentState.DENIED

Filtering events

beforeSendError, beforeSendResource and beforeSendAction receive each event before it is stored. Change it to remove sensitive data, or return null to drop it.

index.js
DataPork.initialize({
  // ...
  beforeSendResource: (event) => {
    // Drop requests to a host you do not want to see
    if (event.resource?.url?.includes('analytics.example.com')) return null;
    return event;
  },
  beforeSendError: (event) => {
    // Edit before it is stored
    if (event.error?.message) {
      event.error.message = event.error.message.replace(/\d{12,}/g, '[number]');
    }
    return event;
  },
});

Custom actions, errors and view data

cart.ts
import { Rum, ActionKind, ErrorOrigin } from '@datapork/react-native';

Rum.recordAction(ActionKind.CUSTOM, 'added_to_cart');
Rum.recordError('Payment declined', ErrorOrigin.CUSTOM, '');

Rum.setViewAttribute('cartSize', 3);
Rum.markViewLoaded();
const sessionId = await Rum.currentSessionId();

Uploading

Events upload every uploadIntervalMs (10 seconds by default). DataPork.flush() uploads what is pending right away and returns a promise, useful before a deliberate exit or in tests.