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:
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.
| Option | Type | Default | What it does |
|---|---|---|---|
| clientToken | string | none | Client token of the application. It is sent with every upload to authenticate the app. |
| applicationId | string | none | ID of the application in DataPork. |
| env | string | none | Environment of this build, for example prod, staging or dev. Use it to filter in the console. |
| intakeUrl | string | none | Full 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
| Option | Type | Default | What it does |
|---|---|---|---|
| service | string | bundle ID | Name of the service the events belong to. By default the Android application ID or the iOS bundle ID. |
| version | string | app version | Version of your app. By default the version name (Android) or the short version (iOS) of the installed build. |
| buildSuffix | string | none | Appended to the version with a dash, for example a build number or a CI run: 1.4.0 becomes 1.4.0-482. |
Sampling
| Option | Type | Default | What it does |
|---|---|---|---|
| sessionSampleRate | number | 100 | Percentage of sessions to track, from 0 to 100. The decision is made once per session. |
| traceSampleRate | number | 100 | Percentage of requests to your own hosts that get trace headers, from 0 to 100. Change it later with DataPork.setTraceSampleRate(). |
What to capture
| Option | Type | Default | What it does |
|---|---|---|---|
| captureTaps | boolean | true | Record taps as actions. |
| captureRequests | boolean | true | Record network requests (fetch and XMLHttpRequest) as resources. |
| captureErrors | boolean | true | Record uncaught JavaScript errors and console.error calls as errors. |
| captureBackground | boolean | false | Also record events that happen while the app is in the background. |
| slowJsTaskMs | number | 0 (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.
| Option | Type | Default | What it does |
|---|---|---|---|
| actionLabelProp | string | none | Name of a prop to read the action name from, for example testID. |
| labelFromAccessibility | boolean | true | Use 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
| Option | Type | Default | What 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
| Option | Type | Default | What it does |
|---|---|---|---|
| uploadIntervalMs | number | 10000 | Delay between upload attempts, in milliseconds. |
| consent | ConsentState | ALLOWED | Initial tracking consent. See Consent below. |
| logLevel | LogLevel | off | Prints 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.
| Option | Type | Default | What it does |
|---|---|---|---|
| beforeSendError | (event) => event | null | none | Called for every error event. |
| beforeSendResource | (event) => event | null | none | Called for every resource (request) event. |
| beforeSendAction | (event) => event | null | none | Called 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:
- the
datapork-action-nameprop, - the prop named by the
actionLabelPropoption, - the
accessibilityLabel(also better for accessibility), - the type of the element, for example
RCTViewfor aPressable.
<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.
// 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:
DataPork.setGlobalAttribute('store', 'madrid');
DataPork.setGlobalAttributes({ experiment: 'new-checkout', locale: 'es' });
DataPork.clearGlobalAttributes(['experiment']);Consent
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.
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.DENIEDFiltering events
beforeSendError, beforeSendResource and beforeSendAction receive each event before it is stored. Change it to remove sensitive data, or return null to drop it.
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
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.