@raccoon.ninja/otel-react 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +433 -0
- package/dist/index.cjs +433 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +185 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.mjs +427 -0
- package/dist/index.mjs.map +1 -0
- package/dist/native/index.cjs +215 -0
- package/dist/native/index.cjs.map +1 -0
- package/dist/native/index.d.mts +100 -0
- package/dist/native/index.d.ts +100 -0
- package/dist/native/index.mjs +211 -0
- package/dist/native/index.mjs.map +1 -0
- package/dist/nextjs/index.cjs +103 -0
- package/dist/nextjs/index.cjs.map +1 -0
- package/dist/nextjs/index.d.mts +77 -0
- package/dist/nextjs/index.d.ts +77 -0
- package/dist/nextjs/index.mjs +101 -0
- package/dist/nextjs/index.mjs.map +1 -0
- package/package.json +125 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 raccoon.ninja
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
# @raccoon.ninja/otel-react
|
|
2
|
+
|
|
3
|
+
Drop-in OpenTelemetry instrumentation for React, React Native, and Next.js.
|
|
4
|
+
|
|
5
|
+
One component. Zero code changes. Traces, logs, and Web Vitals metrics exported via OTLP to any compatible collector.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **One-line setup** via `<OtelProvider>` or `initOtel()`
|
|
10
|
+
- **Auto-instrumentation** for `fetch`, `XMLHttpRequest`, document load, and user interactions
|
|
11
|
+
- **Web Vitals** (LCP, CLS, INP, TTFB, FCP) exported as OTel metrics
|
|
12
|
+
- **Error boundary** that records unhandled errors as spans and logs
|
|
13
|
+
- **Custom spans** via the `useTracer()` hook
|
|
14
|
+
- **OTLP HTTP/JSON** export to any OpenTelemetry-compatible backend
|
|
15
|
+
- **React Native** and **Next.js** support via subpath imports
|
|
16
|
+
- **Vendor-neutral** -- works with Grafana, Jaeger, Datadog, Honeycomb, or any OTLP collector
|
|
17
|
+
- **Tree-shakeable** with `sideEffects: false`, ESM + CJS dual format
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @raccoon.ninja/otel-react
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
React is a peer dependency -- you need React 17, 18, or 19 installed in your project.
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
Wrap your app with `<OtelProvider>`:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { OtelProvider } from '@raccoon.ninja/otel-react';
|
|
33
|
+
|
|
34
|
+
function App() {
|
|
35
|
+
return (
|
|
36
|
+
<OtelProvider serviceName="my-app">
|
|
37
|
+
<RestOfTheApp />
|
|
38
|
+
</OtelProvider>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
That's it. Your app now exports:
|
|
44
|
+
|
|
45
|
+
- Traces for every `fetch()` and `XMLHttpRequest` call
|
|
46
|
+
- Document load timing spans (DNS, TCP, TLS, DOM processing)
|
|
47
|
+
- User interaction spans (clicks)
|
|
48
|
+
- Web Vitals metrics (LCP, CLS, INP, TTFB, FCP)
|
|
49
|
+
|
|
50
|
+
All telemetry is sent to `http://localhost:4318` by default (the standard OTLP HTTP port).
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
### OtelProvider Props
|
|
55
|
+
|
|
56
|
+
| Prop | Type | Default | Description |
|
|
57
|
+
|------|------|---------|-------------|
|
|
58
|
+
| `serviceName` | `string` | **(required)** | Sets the `service.name` resource attribute |
|
|
59
|
+
| `endpoint` | `string` | `http://localhost:4318` | OTLP HTTP collector endpoint |
|
|
60
|
+
| `serviceVersion` | `string` | -- | Sets `service.version` resource attribute |
|
|
61
|
+
| `environment` | `string` | -- | Sets `deployment.environment` resource attribute |
|
|
62
|
+
| `headers` | `Record<string, string>` | -- | Custom headers for OTLP requests (e.g., auth tokens) |
|
|
63
|
+
| `exportTimeout` | `number` | `30000` | Export timeout in milliseconds |
|
|
64
|
+
| `ignoreUrls` | `(string \| RegExp)[]` | -- | URLs to exclude from fetch/XHR instrumentation |
|
|
65
|
+
| `instrumentations` | `InstrumentationConfig` | all enabled | Enable/disable specific auto-instrumentations |
|
|
66
|
+
| `resourceAttributes` | `Record<string, string>` | -- | Additional OTel resource attributes |
|
|
67
|
+
| `extensions` | `OtelExtension[]` | -- | Opt-in extensions (e.g., `withReactRouter()`) |
|
|
68
|
+
| `configureTracing` | `(provider) => void` | -- | Escape hatch to configure the TracerProvider |
|
|
69
|
+
| `configureExporter` | `(exporter) => void` | -- | Escape hatch to configure the OTLP exporter |
|
|
70
|
+
|
|
71
|
+
### Pointing to a Collector
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<OtelProvider
|
|
75
|
+
serviceName="my-app"
|
|
76
|
+
endpoint="https://otel-collector.example.com:4318"
|
|
77
|
+
headers={{ 'x-api-key': 'your-token' }}
|
|
78
|
+
>
|
|
79
|
+
<App />
|
|
80
|
+
</OtelProvider>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Disabling Specific Instrumentations
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
<OtelProvider
|
|
87
|
+
serviceName="my-app"
|
|
88
|
+
instrumentations={{
|
|
89
|
+
fetch: true, // default: true
|
|
90
|
+
xhr: false, // disable XHR instrumentation
|
|
91
|
+
documentLoad: true, // default: true
|
|
92
|
+
userInteraction: false, // disable click tracking
|
|
93
|
+
webVitals: true, // default: true
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<App />
|
|
97
|
+
</OtelProvider>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Excluding URLs from Instrumentation
|
|
101
|
+
|
|
102
|
+
Useful for health checks, analytics endpoints, or any URL that shouldn't generate spans:
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
<OtelProvider
|
|
106
|
+
serviceName="my-app"
|
|
107
|
+
ignoreUrls={[
|
|
108
|
+
/\/health$/,
|
|
109
|
+
/\/analytics/,
|
|
110
|
+
'https://cdn.example.com',
|
|
111
|
+
]}
|
|
112
|
+
>
|
|
113
|
+
<App />
|
|
114
|
+
</OtelProvider>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Imperative API
|
|
118
|
+
|
|
119
|
+
For non-component contexts (testing, scripts, early initialization), use `initOtel()` directly:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { initOtel } from '@raccoon.ninja/otel-react';
|
|
123
|
+
|
|
124
|
+
const otel = initOtel({
|
|
125
|
+
serviceName: 'my-app',
|
|
126
|
+
endpoint: 'https://otel-collector.example.com:4318',
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Later, during cleanup:
|
|
130
|
+
await otel.shutdown();
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`<OtelProvider>` calls `initOtel()` internally and handles shutdown on unmount.
|
|
134
|
+
|
|
135
|
+
## Error Boundary
|
|
136
|
+
|
|
137
|
+
`TracedErrorBoundary` catches unhandled errors in its subtree and records them as both OTel spans and log records:
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import { OtelProvider, TracedErrorBoundary } from '@raccoon.ninja/otel-react';
|
|
141
|
+
|
|
142
|
+
function App() {
|
|
143
|
+
return (
|
|
144
|
+
<OtelProvider serviceName="my-app">
|
|
145
|
+
<TracedErrorBoundary fallback={<div>Something went wrong</div>}>
|
|
146
|
+
<MainContent />
|
|
147
|
+
</TracedErrorBoundary>
|
|
148
|
+
</OtelProvider>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The fallback can also be a render function that receives the error and a reset callback:
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
<TracedErrorBoundary
|
|
157
|
+
fallback={(error, reset) => (
|
|
158
|
+
<div>
|
|
159
|
+
<p>Error: {error.message}</p>
|
|
160
|
+
<button onClick={reset}>Try Again</button>
|
|
161
|
+
</div>
|
|
162
|
+
)}
|
|
163
|
+
onError={(error, errorInfo) => {
|
|
164
|
+
// Optional: additional error reporting
|
|
165
|
+
console.error('Caught by boundary:', error);
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
<RiskyComponent />
|
|
169
|
+
</TracedErrorBoundary>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Each caught error generates:
|
|
173
|
+
- A span with `error.type`, `error.message`, `error.stack`, and `error.component_stack` attributes
|
|
174
|
+
- A log record at `ERROR` severity with the same details
|
|
175
|
+
|
|
176
|
+
## Custom Spans
|
|
177
|
+
|
|
178
|
+
Use the `useTracer()` hook to create custom spans for business-critical operations:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import { useTracer } from '@raccoon.ninja/otel-react';
|
|
182
|
+
|
|
183
|
+
function CheckoutForm() {
|
|
184
|
+
const tracer = useTracer();
|
|
185
|
+
|
|
186
|
+
const handleSubmit = async (data: FormData) => {
|
|
187
|
+
const span = tracer.startSpan('checkout.submit');
|
|
188
|
+
span.setAttribute('cart.item_count', data.items.length);
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
await submitOrder(data);
|
|
192
|
+
span.setStatus({ code: 1 }); // SpanStatusCode.OK
|
|
193
|
+
} catch (error) {
|
|
194
|
+
span.setStatus({ code: 2, message: String(error) }); // SpanStatusCode.ERROR
|
|
195
|
+
span.recordException(error as Error);
|
|
196
|
+
throw error;
|
|
197
|
+
} finally {
|
|
198
|
+
span.end();
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
You can provide a custom tracer name and version:
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
const tracer = useTracer('my-feature', '1.0.0');
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Extensions
|
|
213
|
+
|
|
214
|
+
### React Router
|
|
215
|
+
|
|
216
|
+
Opt-in route change tracing for React Router v6/v7:
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
import { OtelProvider, withReactRouter } from '@raccoon.ninja/otel-react';
|
|
220
|
+
|
|
221
|
+
function App() {
|
|
222
|
+
return (
|
|
223
|
+
<OtelProvider
|
|
224
|
+
serviceName="my-app"
|
|
225
|
+
extensions={[withReactRouter()]}
|
|
226
|
+
>
|
|
227
|
+
<RouterProvider router={router} />
|
|
228
|
+
</OtelProvider>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## What Gets Collected
|
|
234
|
+
|
|
235
|
+
### Traces (Automatic)
|
|
236
|
+
|
|
237
|
+
| Signal | Source | What It Captures |
|
|
238
|
+
|--------|--------|-----------------|
|
|
239
|
+
| `fetch()` calls | `@opentelemetry/instrumentation-fetch` | URL, method, status, duration |
|
|
240
|
+
| `XMLHttpRequest` | `@opentelemetry/instrumentation-xml-http-request` | URL, method, status, duration |
|
|
241
|
+
| Document load | `@opentelemetry/instrumentation-document-load` | DNS, TCP, TLS, DOM processing |
|
|
242
|
+
| User interactions | `@opentelemetry/instrumentation-user-interaction` | Click events on DOM elements |
|
|
243
|
+
| Error boundary | `TracedErrorBoundary` | Uncaught errors with component stack |
|
|
244
|
+
|
|
245
|
+
### Metrics (Automatic)
|
|
246
|
+
|
|
247
|
+
| Metric | Type | Description |
|
|
248
|
+
|--------|------|-------------|
|
|
249
|
+
| `web_vitals.lcp` | Histogram | Largest Contentful Paint (ms) |
|
|
250
|
+
| `web_vitals.cls` | Histogram | Cumulative Layout Shift |
|
|
251
|
+
| `web_vitals.inp` | Histogram | Interaction to Next Paint (ms) |
|
|
252
|
+
| `web_vitals.ttfb` | Histogram | Time to First Byte (ms) |
|
|
253
|
+
| `web_vitals.fcp` | Histogram | First Contentful Paint (ms) |
|
|
254
|
+
|
|
255
|
+
Each metric includes `web_vitals.rating` (`good`, `needs-improvement`, `poor`) and `page.url` attributes.
|
|
256
|
+
|
|
257
|
+
### Resource Attributes (Automatic)
|
|
258
|
+
|
|
259
|
+
| Attribute | Source |
|
|
260
|
+
|-----------|--------|
|
|
261
|
+
| `service.name` | Config (required) |
|
|
262
|
+
| `service.version` | Config (optional) |
|
|
263
|
+
| `deployment.environment` | Config (optional) |
|
|
264
|
+
| `telemetry.sdk.name` | `@raccoon.ninja/otel-react` |
|
|
265
|
+
| `telemetry.sdk.version` | Package version |
|
|
266
|
+
| `browser.language` | `navigator.language` |
|
|
267
|
+
| `browser.user_agent` | `navigator.userAgent` |
|
|
268
|
+
| `browser.platform` | `navigator.platform` |
|
|
269
|
+
|
|
270
|
+
Custom attributes can be added via the `resourceAttributes` prop.
|
|
271
|
+
|
|
272
|
+
## React Native
|
|
273
|
+
|
|
274
|
+
Import from `@raccoon.ninja/otel-react/native`:
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { initOtel } from '@raccoon.ninja/otel-react/native';
|
|
278
|
+
|
|
279
|
+
const otel = await initOtel({
|
|
280
|
+
serviceName: 'my-rn-app',
|
|
281
|
+
endpoint: 'https://otel-collector.example.com:4318',
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Key differences from the browser entry:
|
|
286
|
+
- Uses `BasicTracerProvider` instead of `WebTracerProvider` (no DOM APIs)
|
|
287
|
+
- Only `fetch` instrumentation is enabled (no document load, user interaction, or Web Vitals)
|
|
288
|
+
- XHR is disabled by default to avoid duplicate spans (React Native's `fetch` polyfills over XHR)
|
|
289
|
+
- Uses `AppState` change listener for flush instead of `visibilitychange`
|
|
290
|
+
|
|
291
|
+
### React Navigation
|
|
292
|
+
|
|
293
|
+
Track navigation state changes as spans:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import { initOtel, withReactNavigation, createNavigationTracker } from '@raccoon.ninja/otel-react/native';
|
|
297
|
+
|
|
298
|
+
const otel = await initOtel({
|
|
299
|
+
serviceName: 'my-rn-app',
|
|
300
|
+
extensions: [withReactNavigation()],
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const onStateChange = createNavigationTracker();
|
|
304
|
+
|
|
305
|
+
function App() {
|
|
306
|
+
return (
|
|
307
|
+
<NavigationContainer onStateChange={onStateChange}>
|
|
308
|
+
{/* screens */}
|
|
309
|
+
</NavigationContainer>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Next.js
|
|
315
|
+
|
|
316
|
+
Next.js requires a two-part setup (server + client).
|
|
317
|
+
|
|
318
|
+
### Server-Side (`instrumentation.ts`)
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
import { initOtelServer } from '@raccoon.ninja/otel-react/nextjs';
|
|
322
|
+
|
|
323
|
+
export async function register() {
|
|
324
|
+
await initOtelServer({
|
|
325
|
+
serviceName: 'my-nextjs-app',
|
|
326
|
+
endpoint: 'https://otel-collector.example.com:4318',
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Client-Side (Root Layout)
|
|
332
|
+
|
|
333
|
+
```tsx
|
|
334
|
+
// app/providers.tsx
|
|
335
|
+
'use client';
|
|
336
|
+
|
|
337
|
+
import { OtelProvider } from '@raccoon.ninja/otel-react';
|
|
338
|
+
|
|
339
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
340
|
+
return (
|
|
341
|
+
<OtelProvider serviceName="my-nextjs-app">
|
|
342
|
+
{children}
|
|
343
|
+
</OtelProvider>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// app/layout.tsx
|
|
348
|
+
import { Providers } from './providers';
|
|
349
|
+
|
|
350
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
351
|
+
return (
|
|
352
|
+
<html>
|
|
353
|
+
<body>
|
|
354
|
+
<Providers>{children}</Providers>
|
|
355
|
+
</body>
|
|
356
|
+
</html>
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## CORS Configuration
|
|
362
|
+
|
|
363
|
+
If your app and collector are on different origins, configure CORS on the collector. Example for the OpenTelemetry Collector:
|
|
364
|
+
|
|
365
|
+
```yaml
|
|
366
|
+
# otel-collector-config.yaml
|
|
367
|
+
receivers:
|
|
368
|
+
otlp:
|
|
369
|
+
protocols:
|
|
370
|
+
http:
|
|
371
|
+
endpoint: 0.0.0.0:4318
|
|
372
|
+
cors:
|
|
373
|
+
allowed_origins:
|
|
374
|
+
- "https://your-app.com"
|
|
375
|
+
- "http://localhost:3000"
|
|
376
|
+
allowed_headers:
|
|
377
|
+
- "Content-Type"
|
|
378
|
+
- "X-Requested-With"
|
|
379
|
+
max_age: 7200
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## Graceful Shutdown
|
|
383
|
+
|
|
384
|
+
The package automatically flushes pending telemetry:
|
|
385
|
+
|
|
386
|
+
- On `visibilitychange` (when the tab becomes hidden)
|
|
387
|
+
- On `beforeunload` (when the page is about to close)
|
|
388
|
+
- On `<OtelProvider>` unmount
|
|
389
|
+
- When `otel.shutdown()` is called (imperative API)
|
|
390
|
+
|
|
391
|
+
This ensures telemetry is not lost during page navigation or tab close.
|
|
392
|
+
|
|
393
|
+
## API Reference
|
|
394
|
+
|
|
395
|
+
### Exports from `@raccoon.ninja/otel-react`
|
|
396
|
+
|
|
397
|
+
| Export | Type | Description |
|
|
398
|
+
|--------|------|-------------|
|
|
399
|
+
| `OtelProvider` | Component | React provider that initializes OTel on mount |
|
|
400
|
+
| `TracedErrorBoundary` | Component | Error boundary that records errors as spans/logs |
|
|
401
|
+
| `initOtel` | Function | Imperative initialization, returns `OtelHandle` |
|
|
402
|
+
| `useTracer` | Hook | Get an OTel `Tracer` for custom spans |
|
|
403
|
+
| `withReactRouter` | Function | Extension for React Router route tracing |
|
|
404
|
+
| `OtelOptions` | Type | Configuration interface |
|
|
405
|
+
| `OtelHandle` | Type | Handle with `shutdown()` method |
|
|
406
|
+
| `OtelExtension` | Type | Extension function signature |
|
|
407
|
+
| `InstrumentationConfig` | Type | Instrumentation toggle config |
|
|
408
|
+
| `OtelProviderProps` | Type | Props for `<OtelProvider>` |
|
|
409
|
+
| `TracedErrorBoundaryProps` | Type | Props for `<TracedErrorBoundary>` |
|
|
410
|
+
|
|
411
|
+
### Exports from `@raccoon.ninja/otel-react/native`
|
|
412
|
+
|
|
413
|
+
| Export | Type | Description |
|
|
414
|
+
|--------|------|-------------|
|
|
415
|
+
| `initOtel` | Function | RN-specific initialization (async) |
|
|
416
|
+
| `withReactNavigation` | Function | Extension for React Navigation |
|
|
417
|
+
| `createNavigationTracker` | Function | Creates `onStateChange` handler |
|
|
418
|
+
|
|
419
|
+
### Exports from `@raccoon.ninja/otel-react/nextjs`
|
|
420
|
+
|
|
421
|
+
| Export | Type | Description |
|
|
422
|
+
|--------|------|-------------|
|
|
423
|
+
| `initOtelServer` | Function | Server-side initialization for `instrumentation.ts` |
|
|
424
|
+
|
|
425
|
+
## Requirements
|
|
426
|
+
|
|
427
|
+
- **Node.js** >= 18
|
|
428
|
+
- **React** 17, 18, or 19
|
|
429
|
+
- An OTLP-compatible collector (e.g., [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/), [Grafana Alloy](https://grafana.com/docs/alloy/), or any vendor's OTLP endpoint)
|
|
430
|
+
|
|
431
|
+
## License
|
|
432
|
+
|
|
433
|
+
MIT
|