# Exporting and networking

Copy as Markdown[Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Frum%2Fsdk-installation%2Freact-native%2Freact-native-plugin%2Fconfiguration%2Fexporting-and-networking.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fuser-guides%2Frum%2Fsdk-installation%2Freact-native%2Freact-native-plugin%2Fconfiguration%2Fexporting-and-networking.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)

### Traces Exporter[​](#traces-exporter "Direct link to Traces Exporter")

Receive OTLP-formatted trace batches from the native SDK in your JavaScript code. Use this to forward spans to an OTLP-compatible backend (e.g. Jaeger, custom collector) alongside Coralogix.

```
await CoralogixRum.init({

  // ...

  tracesExporter: (data) => {

    // data.resource_spans contains OTLP JSON-format span data

    sendToMyOtlpBackend(JSON.stringify(data));

  },

});
```

The callback receives a `TraceExporterData` object following the OTLP JSON format:

```
{

  resource_spans: [

    {

      resource: { attributes: [{ key: string, value: { string_value: string } }] },

      scope_spans: [

        {

          scope: { name: string, version?: string },

          spans: [

            {

              trace_id: string,

              span_id: string,

              parent_span_id?: string,

              name: string,

              start_time_unix_nano: string,

              end_time_unix_nano: string,

              attributes: [{ key: string, value: {...} }],

              status: { code: string },

            }

          ]

        }

      ]

    }

  ]

}
```

Note

The callback fires once per native export batch, which typically contains several spans rather than one per span.

### beforeSend[​](#beforesend "Direct link to beforeSend")

Enable event access and modification before sending to Coralogix, supporting content modification, and event discarding.

```
await CoralogixRum.init({

  // ...

  beforeSend: (event) => {

    // Discard events from @company.com users.

    if (event.session_context.user_email?.endsWith('@company.com')) {

      return null;

    }



    // Redact sensitive information.

    event.session_context.user_email = '***@***';



    return event;

  },

});
```

#### Telling excluded events apart in `beforeSend`[​](#telling-excluded-events-apart-in-beforesend "Direct link to telling-excluded-events-apart-in-beforesend")

Every event carries `session_context.isSessionSampledIn`. `false` means the event reached you only because its category is listed in [`excludeFromSampling`](#exclude-from-sampling) — the session itself was sampled out. Use it to apply your own filtering on top of the exclude list, for example to keep only error-severity events from sampled-out sessions:

```
await CoralogixRum.init({

  // ...

  sessionSampleRate: 10,

  excludeFromSampling: ['errors', 'logs'],

  beforeSend: (event) => {

    // Default to `true`: a native SDK older than the one this plugin pins does not

    // stamp the flag, and `!undefined` would drop everything but errors.

    const sampledIn = event.session_context.isSessionSampledIn ?? true;



    // Session sampled out: forward only error-severity events, drop the rest.

    if (

      !sampledIn &&

      event.event_context?.severity !== CoralogixLogSeverity.Error

    ) {

      return null;

    }



    return event;

  },

});
```

Note

Always read it as `isSessionSampledIn ?? true`. The field is absent on native SDKs that predate it, and the SDK never invents a value it was not given.

`isSessionSampledIn` is read-only: it reports the SDK's sampling decision for the session, so assigning to it has no effect on the sent event. The decision is recorded when the event is created, so events buffered across a session rotation keep the decision of the session they belong to.

#### Read-only fields[​](#read-only-fields "Direct link to Read-only fields")

Some fields exist for the callback to *read*, not to change. The SDK restores its own values after `beforeSend` returns, so assigning to any of them — or injecting one into a returned object — has no effect on the sent event.

Inside `session_context`, **only** the user fields are editable:

| Editable                                              | Read-only                                                                   |
| ----------------------------------------------------- | --------------------------------------------------------------------------- |
| `user_id`, `user_name`, `user_email`, `user_metadata` | `session_id`, `session_creation_date`, `isSessionSampledIn`, `hasRecording` |

Any other key in `session_context` — including one your callback invents — is discarded, so session identity cannot be forged.

Deleting an editable field is honored, since redaction-by-deletion is a valid use. That means returning a *hand-built partial* `session_context` drops the user fields you left out; edit the event you were given (or spread it) if you want to change one field and keep the rest.

These top-level fields are read-only too, because rewriting them would corrupt trace correlation, event dedup or product analytics rather than redact anything:

`spanId`, `traceId`, `fingerPrint`, `timestamp`, `platform`, `mobile_sdk`, `snapshot_context`, `isSnapshotEvent`, `prev_session`, `view_number`, `isNavigationEvent`

`view_number` and `isNavigationEvent` record what the SDK observed when it built the event. They are deliberately not recomputed from `event_context.type`, so if you relabel an event the two can differ — filter on `isNavigationEvent` when you need "was this actually a navigation".

Everything else — `event_context` (including `severity`), `labels`, `error_context`, `log_context`, `network_request_context`, `view_context`, `environment`, `device_context`, `device_state`, `version_metadata` — is editable, and returning `null` still drops the event entirely.

### Proxy URL[​](#proxy-url "Direct link to Proxy URL")

Proxy configuration to route requests.<br />By specifying a proxy URL, all RUM data will be directed to this URL via the POST method. However, it is necessary for this data to be subsequently relayed from the proxy to Coralogix. The Coralogix route for each request that is sent to the proxy is available in the request's cxforward parameter (for example, <https://www.your-proxy.com/endpoint?cxforward=https%3A%2F%2Fingress.eu1.rum-ingress-coralogix.com%2Fbrowser%2Fv1beta%2Flogs>).

```
await CoralogixRum.init({

  // ...

  coralogixDomain: 'EU1',

  proxyUrl: 'https://www.your-proxy.com/endpoint',

});
```
